Referenciando outros módulos no Atexit
Pergunta
Eu tenho uma função responsável por matar um processo infantil quando o programa termina:
class MySingleton:
def __init__(self):
import atexit
atexit.register(self.stop)
def stop(self):
os.kill(self.sel_server_pid, signal.SIGTERM)
No entanto, recebo uma mensagem de erro quando esta função é chamada:
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'
Parece o os
e signal
Os módulos são descarregados antes atexit
é chamado. Reimportando -os resolve o problema, mas esse comportamento me parece estranho - esses módulos são importados antes de eu registrar meu manipulador, então por que eles são descarregados antes do meu próprio manipulador de saída?
Solução
Não há fortes garantias sobre a ordem em que as coisas são destruídas no tempo de encerramento do programa, por isso é melhor garantir atexit
-Funções registradas são independentes. Por exemplo, no seu caso:
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)
Isso é preferível a reimportar módulos (que podem causar desaceleração da resumo da rescisão do programa e até os loops internos, embora esse risco seja menor para módulos "fornecidos pelo sistema", como os módulos como os
).