5 ответов:
Да, вы можете установить обработчик прерываний с помощью модуля сигнал, и ждать вечно использованием нарезание резьбы.Событие:
import signal import sys import time def signal_handler(signal, frame): print('You pressed Ctrl+C!') sys.exit(0) signal.signal(signal.SIGINT, signal_handler) print('Press Ctrl+C') forever = threading.Event() forever.wait()
Если все, что вы хотите, это не показывать трассировку, сделайте свой код следующим образом:
## all your app logic here def main(): ## whatever your app does. if __name__ == "__main__": try: main() except KeyboardInterrupt: # do nothing here pass(Да, я знаю, что это не дает прямого ответа на вопрос, но не совсем понятно, почему необходимость в блоке try / except нежелательна - возможно, это делает его менее раздражающим для OP)
альтернативой настройке собственного обработчика сигналов является использование контекстного менеджера для перехвата исключения и его игнорирования:
>>> class CleanExit(object): ... def __enter__(self): ... return self ... def __exit__(self, exc_type, exc_value, exc_tb): ... if exc_type is KeyboardInterrupt: ... return True ... return exc_type is None ... >>> with CleanExit(): ... input() #just to test it ... >>>Это удаляет
try-exceptблок при сохранении некоторого явного упоминания о том, что происходит.Это также позволяет игнорировать прерывание только в некоторых частях вашего кода без необходимости устанавливать и снова сбрасывать обработчики сигналов каждый раз.
Я знаю, что это старый вопрос, но я пришел сюда первым, а затем обнаружил
atexitмодуль. Я еще не знаю о его кросс-платформенном послужном списке или полном списке предостережений, но до сих пор это именно то, что я искал, пытаясь справиться с post-KeyboardInterruptочистка на Linux. Просто хотел бросить в другой способ подхода к проблеме.Я хочу сделать очистку после выхода в контексте операций с тканью, поэтому обертывание всего в
try/exceptне было вариант для меня. Я чувствую, чтоatexitможет быть хорошо подходит в такой ситуации, когда ваш код не находится на верхнем уровне потока управления.
atexitочень способный и читаемый из коробки, например:import atexit def goodbye(): print "You are now leaving the Python sector." atexit.register(goodbye)вы также можете использовать его в качестве оформителя (в 2.6; этот пример из документации):
import atexit @atexit.register def goodbye(): print "You are now leaving the Python sector."если вы хотите сделать его специфичным для
KeyboardInterruptтолько, ответ другого человека на этот вопрос, вероятно, лучше.но обратите внимание, что
atexitмодуль - это только ~70 строк кода, и было бы нетрудно создать аналогичную версию, которая обрабатывает исключения по-разному, например, передавая исключения в качестве аргументов функциям обратного вызова. (Ограничениеatexitэто гарантировало бы модифицированную версию: в настоящее время я не могу представить себе способ для функций exit-callback-знать об исключениях;atexitобработчик ловит исключение, вызывает ваш обратный вызов(ы), а затем повторно вызывает это исключение. Но вы могли бы сделать это по-другому.)для получения дополнительной информации см.:
- официальная документация о
atexit- The Python модуль недели пост хорошее интро
вы можете запретить печать трассировки стека для
KeyboardInterrupt, безtry: ... except KeyboardInterrupt: pass(наиболее очевидное и приемлемое "лучшее" решение, но вы уже знаете его и попросили что-то еще), заменивsys.excepthook. Что-то вродеdef custom_excepthook(type, value, traceback): if type is KeyboardInterrupt: return # do nothing else: sys.__excepthook__(type, value, traceback)
Comments