2010-04-03 2 views
2

У меня есть функция, которая отвечает за убийство дочернего процесса, когда программа заканчивается:Ссылка на других модулей в atexit

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. Повторное импортирование их решает проблему, но это поведение кажется мне странным - эти модули импортируются до того, как я зарегистрирую обработчик, так почему они выгружаются до того, как мой собственный обработчик выхода работает?

ответ

6

Нет никаких сильных гарантий относительно порядка, в котором вещи разрушаются в момент завершения программы, поэтому лучше всего обеспечить, чтобы 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).