Удалить трассировку в 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")
Другие вопросы по тегам