#python #signals
Вопрос:
У меня есть приложение, которое выглядит так:
while True:
try:
self.try_to_read_usb_device()
break
except:
time.sleep(1)
У меня также есть SIGALRM
обработчик, который должен выйти из программы в случае, если она где-то застряла:
def alarm_signal_handler(signal, frame):
# Something went wrong
exit(1)
Однако exit(1)
просто попадается на попытку/исключение и отбрасывается, так как это то, что делает этот конкретный except
.
Это для меня совершенно неожиданно.
В полном приложении будет много попыток/исключений, и я не вижу, чтобы я добавлял
except SystemExit:
exit(1)
или что-то для всех них.
Есть идеи, как мне следует обращаться с этим прецедентом?
Ответ №1:
Грязный путь
Вы можете использовать os._exit
вместо sys.exit
.
Обратите внимание, что у этого есть очевидные недостатки именно потому, что он не пройдет через исключение:
Завершите процесс со статусом n, не вызывая обработчики очистки, не очищая буферы stdio и т. Д.
Правильный путь
Я бы рекомендовал вместо этого изменить обработку исключений , чтобы перехватывать только вещи, от которых они наследуются Exception
, потому что SystemExit
не наследуются Exception
именно по этой причине, поэтому они не будут пойманы случайно:
except Exception:
Смотрите также SystemExit
документацию:
Это исключение вызывается
sys.exit()
функцией. Он наследуется отBaseException
вместоException
, чтобы его случайно не поймал код, который ловитException
. Это позволяет исключению правильно распространяться и вызывать выход интерпретатора.
Это также относится KeyboardInterrupt
, кстати, к — Ctrl C будет пойман, except:
но не except Exception:
пойман .
Это довольно хорошо проиллюстрировано на диаграмме иерархии исключений в документах Python, которую вы можете найти здесь.