سؤال

هل هناك أي طريقة لتشغيل أمر آخر قبل إيقاف البرنامج النصي من 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)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top