Python: почему `sys.exit (msg)`, вызванный из потока, не выводит `msg` в stderr? - PullRequest
8 голосов
/ 31 июля 2009

Сегодня я столкнулся с тем фактом, что 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() должен быть указатель на то, что сообщение не распечатывается из потоков.

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

С уважением,

Ян-Филипп Герке

Ответы [ 2 ]

6 голосов
/ 31 июля 2009

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

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

0 голосов
/ 31 июля 2009

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

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

...