在atexit中引用其他模块

Dmi*_*erg 2 python atexit

我有一个函数负责在程序结束时终止子进程:

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

    def stop(self):
        os.kill(self.sel_server_pid, signal.SIGTERM)
Run Code Online (Sandbox Code Playgroud)

但是,当调用此函数时,我收到错误消息:

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'
Run Code Online (Sandbox Code Playgroud)

在调用之前看起来像ossignal模块被卸载了atexit.重新导入它们解决了这个问题,但这种行为对我来说似乎很奇怪 - 这些模块是在我注册我的处理程序之前导入的,所以为什么在我自己的退出处理程序运行之前它们被卸载了?

Ale*_*lli 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)
Run Code Online (Sandbox Code Playgroud)

这比重新导入模块更好(这可能会导致程序终止速度减慢甚至无限循环,尽管"系统提供的"模块的风险较小,例如os).