كيفية تشغيل وظيفة أخيرة قبل التقدم في بيثون؟
سؤال
هل هناك أي طريقة لتشغيل أمر آخر قبل إيقاف البرنامج النصي من Python قيد التشغيل من خلال القتل من قبل بعض النصوص الأخرى، مقاطعة لوحة المفاتيح، إلخ.
المحلول
import time
try:
time.sleep(10)
finally:
print "clean up"
clean up
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
KeyboardInterrupt
إذا كنت بحاجة إلى التقاط مقاطعات نظام التشغيل الأخرى، فابحث في وحدة الإشارة:
http://docs.python.org/library/signal.html.
مثال إشارة
from signal import *
import sys, time
def clean(*args):
print "clean me"
sys.exit(0)
for sig in (SIGABRT, SIGBREAK, SIGILL, SIGINT, SIGSEGV, SIGTERM):
signal(sig, clean)
time.sleep(10)
نصائح أخرى
يمكنك استخدام atexit
وحدة. مع ذلك، يمكنك تسجيل وظيفة سيتم استدعاءها في إنهاء البرنامج. مثال من هنا: http://docs.python.org/library/atexit.html.
try:
_count = int(open("/tmp/counter").read())
except IOError:
_count = 0
def incrcounter(n):
global _count
_count = _count + n
def savecounter():
open("/tmp/counter", "w").write("%d" % _count)
import atexit
atexit.register(savecounter)
يمكنك أيضا تمرير معلمات الكلمات الأساسية والكلمة الرئيسية إلى الوظيفة التي تريد استدعاءها في إنهاء البرنامج.
لاحظ أن هناك بعض الظروف المدرجة في المستندات التي لن يتم استدعاؤها لمعالجتك:
ملحوظة: لا يتم استدعاء الوظائف المسجلة عبر هذه الوحدة عندما يقتل البرنامج بسبب إشارة غير معاملة من قبل بيثون، عندما يتم اكتشاف خطأ داخلي فادح ثياب، أو متى
os._exit()
يسمى.
على هذا النحو، قد ترغب في تسجيل معالج إشارة أيضا.
import signal
import sys
import time
def cleanup(*args):
print 'Exiting'
sys.exit(0)
signal.signal(signal.SIGINT, cleanup)
signal.signal(signal.SIGTERM, cleanup)
while True:
time.sleep(60) # less busy loop
مع الاعتذار "غير معروف" لأخذ إجابتهم وتصحيحها كما لو كانت إجابتي الخاصة، ولكن تم رفض تعديلاتي.
يحتوي الإجابة المعتمدة على خطأ سيؤدي إلى segfault.
لا يمكنك استخدام SYS.EXIT () في معالج إشارة، ولكن يمكنك استخدام OS.EXIT بحيث يصبح:
from signal import *
import os, time
def clean(*args):
print "clean me"
os._exit(0)
for sig in (SIGABRT, SIGINT, SIGTERM):
signal(sig, clean)
time.sleep(10)
يمكن استخدام Sigbreak إذا كان النظام الأساسي المستهدف هو Windows.
اعتمادا على حالة الاستخدام والحاجة إلى التنظيف في حالة وجود أخطاء قاتلة - يمكنك إضافة SIGSEGV و SIGILL ولكن بشكل عام لا ينصح بهذا لأن حالة البرنامج قد تكون مثل هذه الحلقة اللانهائية.
استخدم وحدة ATEXIT لتسجيل وظيفة سيتم استدعاؤها في النهاية.
import atexit
atexit.register(some_function)