سؤال

لدي وظيفة مسؤولة عن قتل عملية الطفل عندما ينتهي البرنامج:

class MySingleton:
    def __init__(self):
        import atexit
        atexit.register(self.stop)

    def stop(self):
        os.kill(self.sel_server_pid, signal.SIGTERM)

ومع ذلك ، أحصل على رسالة خطأ عندما تسمى هذه الوظيفة:

Traceback (most recent call last):
File "/usr/lib/python2.5/atexit.py", line 24, in _run_exitfuncs
   func(*targs, **kargs)
File "/home/commando/Development/Diploma/streaminatr/stream/selenium_tests.py", line 66, in stop
   os.kill(self.sel_server_pid, signal.SIGTERM)
AttributeError: 'NoneType' object has no attribute 'kill'

يشبه os و signal يتم تفريغ الوحدات النمطية من قبل atexit يسمى. إعادة استيرادهم يحل المشكلة ، لكن هذا السلوك يبدو غريبًا بالنسبة لي - يتم استيراد هذه الوحدات قبل أن أسجل معالجتي ، فلماذا يتم تفريغها قبل تشغيل معالج الخروج الخاص بي؟

هل كانت مفيدة؟

المحلول

لا توجد ضمانات قوية حول الترتيب الذي تدمر به الأمور في وقت إنهاء البرنامج ، لذلك من الأفضل التأكد atexitالوظائف المسجلة محتوى ذاتيا. على سبيل المثال ، في حالتك:

class MySingleton:
    def __init__(self):
        import atexit
        atexit.register(self.stop)
        self._dokill = os.kill
        self._thesig = signal.SIGTERM

    def stop(self):
        self._dokill(self.sel_server_pid, self._thesig)

هذا هو الأفضل من إعادة استيراد الوحدات النمطية (التي يمكن أن تسبب تباطؤ إنهاء البرنامج وحتى الحلقات التي لا تنتهي ، على الرغم من أن هذا الخطر أقل بالنسبة للوحدات النمطية "المذكورة في النظام" مثل os).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top