Python: Por que `sys.exit (msg)` chamado de um thread não imprimir `msg` para stderr?
-
05-07-2019 - |
Pergunta
Hoje eu corri contra o fato, que sys.exit()
chamado de um thread filho não matar o processo principal. Eu não sabia disso antes, e isso é bom, mas eu precisava de muito tempo para perceber isso. Ele teria poupado muito, muito tempo , se sys.exit(msg)
teria impresso msg
para stderr
. Mas isso não aconteceu.
Descobriu-se que não era um verdadeiro erro no meu aplicativo; que chamou sys.exit(msg)
com um erro significativo de uma forma volitiva - mas eu simplesmente não conseguia ver este
Nos docs para sys.exit()
afirma-se :
"[...] qualquer outro objeto é impresso para sys.stderr
e resulta em um código de saída de 1"
Esta é não é verdade para uma chamada de um thread criança, onde sys.exit()
obviamente, comporta-se como thread.exit()
:
"Levante a exceção SystemExit. Quando não estiver travado, isso fará com que o fio de saída silenciosamente "
Eu acho que quando um programador quer sys.exit(msg)
para imprimir uma mensagem de erro, então isso deve apenas ser impresso - independente do lugar de onde ele é chamado. Por que não? Actualmente, eu não vejo nenhuma razão. Pelo menos deve haver uma dica nos docs para sys.exit()
que a mensagem não é impresso a partir de fios.
O que você acha? Por que as mensagens de erro escondido de tópicos? Isso faz sentido?
Com os melhores cumprimentos,
Jan-Philip Gehrcke
Solução
Eu concordo que os docs Python estão incorretos, ou talvez mais precisamente incompleta, sobre sys.exit e SystemExit quando chamado / levantada por outros que o principal tópicos; por favor, abra uma questão doc sobre o rastreador on-line Python assim que este pode ser abordada em um futuro iteração dos docs (provavelmente um futuro próximo um - correções doc são mais fáceis e mais suave do que correções de código; -)
. O remédio é muito fácil, é claro - só embrulhar qualquer função que você está usando como alvo de uma threading.Thread
com um decorador que faz um try
/ except SystemExit, e:
em torno dele, e executa a "escrever para stderr" funcionalidade extra que você requerem (ou, talvez melhor, utiliza uma chamada logging.error vez) antes de terminar. Mas, com a emissão doc que você apontar corretamente, é difícil pensar em fazer que a menos que e até que se encontrou com o problema e de fato teve de passar algum tempo na depuração para fixá-lo, como você teve que fazer (em nome coletivo dos desenvolvedores python núcleo - sorry).
Outras dicas
Nem todos os segmentos em python são iguais. Chamando sys.exit de um segmento, na verdade não sair do sistema. Assim, sys.exit telefone () a partir de um segmento de criança é sem sentido, por isso faz sentido que ele não se comportar da maneira esperada.
conversações Esta href="http://docs.python.org/library/threading.html" página mais sobre enfiando objetos, e as diferenças entre fios e o especial "principal" thread.