Удалить трассировку в Python на Ctrl-C
Есть ли способ предотвратить появление обратных трассировок при нажатии Ctrl+c, т.е. KeyboardInterrupt
в скрипте Python?
9 ответов
import sys
try:
# your code
except KeyboardInterrupt:
sys.exit(0) # or 1, or whatever
Это самый простой способ, при условии, что вы все еще хотите выйти, когда вы получаете Ctrl+c.
Если вы хотите поймать его без попытки / кроме, вы можете использовать такой рецепт, используя signal
модуль, за исключением того, что он не работает для меня в Windows..
Попробуй это:
import signal
signal.signal(signal.SIGINT, lambda x,y: sys.exit(0))
Таким образом, вам не нужно оборачивать все в обработчик исключений.
Поймать KeyboardInterrupt
:
try:
# do something
except KeyboardInterrupt:
pass
В соответствии с Правильная обработка SIGINT/SIGQUIT , единственный способ правильно выйти, если вы поймали SIGINT, - это впоследствии убить себя с помощью сигнала SIGINT (см. Раздел « Как быть правильной программой »). Неправильно пытаться подделать правильный код выхода. Для получения дополнительной информации об этом, проверьте также Почему «Выполнение выхода 130 не то же самое, что смерть от SIGINT»? на Unix Stack Exchange.
Кажется, что все ответы здесь, которые выходят из нуля, на самом деле демонстрируют программы, которые ведут себя неправильно. Желательно не скрывать, что вас прервали, чтобы вызывающая сторона (обычно оболочка) знала, что делать.
В Python распечатка трассировки на stderr исходит из значения по умолчанию.sys.excepthook
поведение. Итак, чтобы подавить спам с трассировкой, я решил решить проблему непосредственно в причине, заменив ловушку исключения на прерывание клавиатуры, а затем сохранив правильный код выхода, повторно вызвав исходное исключение:
import sys, time
def _no_traceback_excepthook(exc_type, exc_val, traceback):
pass
def main():
try:
# whatever your program does here...
print("hello world..")
time.sleep(42)
except KeyboardInterrupt:
# whatever cleanup code you need here...
print("bye")
if sys.excepthook is sys.__excepthook__:
sys.excepthook = _no_traceback_excepthook
raise
if __name__ == "__main__":
main()
Результат такой:
$ python3 /tmp/example.py
hello world..
^Cbye
$ echo $?
130
Если у вас нет никаких действий по очистке для выполнения, и все, что вы хотели сделать, это подавить печать трассировки при прерывании, может быть проще просто установить это по умолчанию:
import sys
def _no_traceback_excepthook(exc_type, exc_val, traceback):
if isinstance(exc_val, KeyboardInterrupt):
return
sys.__excepthook__(exc_type, exc_val, traceback)
sys.excepthook = _no_traceback_excepthook
try:
your_stuff()
except KeyboardInterrupt:
print("no traceback")
Поймай его с помощью блока try/ кроме:
while True:
try:
print "This will go on forever"
except KeyboardInterrupt:
pass
Также обратите внимание, что по умолчанию интерпретатор завершает работу с кодом состояния 128 + значение SIGINT на вашей платформе (которое в большинстве систем равно 2).
import sys, signal
try:
# code...
except KeyboardInterrupt: # Suppress tracebacks on SIGINT
sys.exit(128 + signal.SIGINT) # http://tldp.org/LDP/abs/html/exitcodes.html
подавить исключение с помощью менеджера контекста :
from contextlib import suppress
def output_forever():
while True:
print('endless script output. Press ctrl + C to exit')
if __name__ == '__main__':
with suppress(KeyboardInterrupt):
output_forever()
import sys
try:
print("HELLO")
english = input("Enter your main launguage: ")
print("GOODBYE")
except KeyboardInterrupt:
print("GET LOST")