Есть ли способ в Python захватить KeyboardInterrupt
событие, не помещая весь код в оператор try
- except
?
Я хочу выйти без следа, если пользователь нажмет Ctrl+ C.
Есть ли способ в Python захватить KeyboardInterrupt
событие, не помещая весь код в оператор try
- except
?
Я хочу выйти без следа, если пользователь нажмет Ctrl+ C.
Да, вы можете установить обработчик прерывания, используя сигнал модуля , и ждать вечно, используя потоки .
import signal
import sys
import time
import threading
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()
while True: continue
. (Вwhile True: pass
любом случае, в таком стиле было бы аккуратнее.) Это было бы очень расточительно; попробуйте что-нибудь вродеwhile True: time.sleep(60 * 60 * 24)
(спать по день - это совершенно произвольная цифра).time
(как следует), не забудьтеimport time
:)Если все, что вы хотите, - это не отображать трассировку, сделайте свой код следующим образом:
(Да, я знаю, что это не дает прямого ответа на вопрос, но не совсем понятно, почему необходимость в блоке try / except нежелательна - возможно, это делает его менее раздражающим для OP)
источник
signal.signal( signal.SIGINT, lambda s, f : sys.exit(0))
всегда делает.Альтернативой настройке собственного обработчика сигналов является использование диспетчера контекста для перехвата исключения и его игнорирования:
Это удаляет блок
try
-except
при сохранении некоторых явных упоминаний о том, что происходит.Это также позволяет игнорировать прерывание только в некоторых частях вашего кода без необходимости каждый раз заново устанавливать и сбрасывать обработчики сигналов.
источник
Я знаю, что это старый вопрос, но я сначала пришел сюда, а потом обнаружил
atexit
модуль. Я еще не знаю его кроссплатформенный послужной список или полный список предостережений, но пока это именно то, что я искал, пытаясь справиться с пост-KeyboardInterrupt
очистку в Linux. Просто хотел по-другому подойти к проблеме.Я хочу выполнить очистку после выхода в контексте операций Fabric, поэтому перенос всего в
try
/except
не был для меня вариантом. Я чувствую, чтоatexit
может хорошо подойти в такой ситуации, когда ваш код не находится на верхнем уровне потока управления.atexit
очень способный и читаемый прямо из коробки, например:Вы также можете использовать его в качестве декоратора (начиная с версии 2.6; этот пример взят из документации):
Если вы хотите сделать это специфичным
KeyboardInterrupt
только для себя, ответ на этот вопрос, вероятно, будет лучше.Но обратите внимание, что
atexit
модуль содержит всего ~ 70 строк кода, и было бы несложно создать аналогичную версию, которая по-другому обрабатывает исключения, например, передает исключения в качестве аргументов функциям обратного вызова. (Ограничениеatexit
этого требует модифицированной версии: в настоящее время я не могу представить, как функции exit-callback узнают об исключениях;atexit
обработчик улавливает исключение, вызывает ваши обратные вызовы, а затем повторно вызывает это исключение. Но вы могли бы сделать это по-другому.)Для получения дополнительной информации см .:
atexit
источник
atexit
работу как для MacOS, так и для Ubuntu 18.04 для python 3.7 и 3.8Вы можете предотвратить печать трассировки стека
KeyboardInterrupt
безtry: ... except KeyboardInterrupt: pass
(наиболее очевидное и, вероятно, «лучшее» решение, но вы уже знаете это и просили что-то еще), заменивsys.excepthook
. Что-то вродеисточник
Я пробовал все предлагаемые решения, но мне пришлось самому импровизировать код, чтобы заставить его работать. Вот мой импровизированный код:
источник
Если кто-то ищет быстрое минимальное решение,
источник