Питон:Почему `sys.exit(msg)`, вызываемый из потока, не выводит `msg` в stderr?

StackOverflow https://stackoverflow.com/questions/1209155

Вопрос

Сегодня я столкнулся с тем фактом, что sys.exit() вызываемый из дочернего потока, не останавливает основной процесс.Я не знал этого раньше, и это нормально, но мне потребовалось много времени, чтобы осознать это.Это спасло бы много-много времени, если sys.exit(msg) напечатал бы msg Для stderr.Но этого не произошло.

Оказалось, что это не была настоящая ошибка в моем приложении;это называлось sys.exit(msg) со значимой ошибкой волевым способом - но я просто не мог этого увидеть.

В документах для sys.exit() это заявлено: "[...] любой другой объект печатается для sys.stderr и приводит к получению кода выхода, равного 1"

Это неправда для вызова из дочернего потока, где sys.exit() очевидно, ведет себя как thread.exit(): "Вызовите исключение SystemExit.Если это не будет перехвачено, это приведет к завершению потока молча"

Я думаю, когда программист хочет sys.exit(msg) чтобы напечатать сообщение об ошибке, это должно быть просто напечатано - независимо от места, откуда оно вызывается.Почему бы и нет?В настоящее время я не вижу никакой причины.По крайней мере, в документах должна быть подсказка для sys.exit() что сообщение не печатается из потоков.

А ты как думаешь?Почему сообщения об ошибках скрыты от потоков?Есть ли в этом смысл?

С наилучшими пожеланиями,

Jan-Philip Gehrcke

Это было полезно?

Решение

Я согласен, что документы Python неверны или, может быть, точнее, неполны в отношении sys.exit и SystemExit при вызове / вызове потоками, отличными от основного;пожалуйста, откройте проблему с документом на онлайн-трекере Python, чтобы это можно было решить в будущей итерации документов (вероятно, в ближайшем будущем - исправления в документе проще и плавнее, чем исправления в коде;-).

Конечно, решение довольно простое - просто оберните любую функцию, которую вы используете в качестве целевого объекта threading.Thread с декоратором, который выполняет try/except SystemExit, e: вокруг этого и выполняет "запись в stderr" дополнительную функциональность, которая вам требуется (или, может быть, лучше, использует вместо этого вызов logging.error) перед завершением работы.Но, учитывая проблему с документом, на которую вы правильно указали, трудно думать об этом до тех пор, пока кто-то не столкнется с проблемой и фактически не потратит некоторое время на отладку, чтобы определить ее, как вам пришлось сделать (от коллективного имени основных разработчиков python - извините!).

Другие советы

Не все потоки в python равны.Вызов sys.exit из потока фактически не приводит к выходу из системы.Таким образом, вызов sys.exit() из дочернего потока бессмыслен, поэтому имеет смысл, что он ведет себя не так, как вы ожидаете.

Это Страница больше рассказывает о потоковых объектах и различиях между потоками и специальным "основным" потоком.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top