Czy w Pythonie jest sposób na przechwycenie KeyboardInterrupt
zdarzenia bez umieszczania całego kodu w instrukcji try
- except
?
Chcę czysto wyjść bez śladu, jeśli użytkownik naciśnie Ctrl+ C.
Czy w Pythonie jest sposób na przechwycenie KeyboardInterrupt
zdarzenia bez umieszczania całego kodu w instrukcji try
- except
?
Chcę czysto wyjść bez śladu, jeśli użytkownik naciśnie Ctrl+ C.
Tak, możesz zainstalować program obsługi przerwań za pomocą sygnału modułu i czekać wiecznie używając wątków .
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
. (W tym stylu i takwhile True: pass
byłoby schludniej.) Byłoby to bardzo marnotrawne; spróbuj czegoś w rodzajuwhile True: time.sleep(60 * 60 * 24)
(spanie przez jeden dzień jest całkowicie arbitralną postacią).time
(tak, jak powinieneś), nie zapomnij oimport time
:)Jeśli chcesz tylko nie pokazywać śledzenia, zrób swój kod w ten sposób:
(Tak, wiem, że to nie jest bezpośrednią odpowiedzią na pytanie, ale nie jest do końca jasne, dlaczego potrzeba blokowania prób / wyjątków jest niepożądana - może to sprawia, że jest mniej irytująca dla OP)
źródło
signal.signal( signal.SIGINT, lambda s, f : sys.exit(0))
zawsze to robi.Alternatywą dla ustawienia własnego modułu obsługi sygnału jest użycie menedżera kontekstu do przechwycenia wyjątku i zignorowania go:
To usuwa blok
try
-except
, zachowując jednocześnie wyraźną wzmiankę o tym, co się dzieje.Pozwala to również zignorować przerwanie tylko w niektórych częściach kodu bez konieczności ustawiania i resetowania za każdym razem programów obsługi sygnału.
źródło
Wiem, że to stare pytanie, ale najpierw przyszedłem tutaj, a potem odkryłem
atexit
moduł. Nie wiem jeszcze o jego osiągnięciach na wielu platformach ani o pełnej liście zastrzeżeń, ale jak dotąd jest to dokładnie to, czego szukałem, próbując obsłużyć poKeyboardInterrupt
czyszczeniu w systemie Linux. Chciałem tylko rzucić okiem na inny sposób podejścia do problemu.Chcę przeprowadzić porządki po wyjściu z programu w kontekście operacji Fabric, więc zawijanie wszystkiego w
try
/except
nie było dla mnie opcją. Wydaje mi się, żeatexit
może być dobrym rozwiązaniem w takiej sytuacji, w której Twój kod nie znajduje się na najwyższym poziomie przepływu kontroli.atexit
jest bardzo wydajny i czytelny po wyjęciu z pudełka, na przykład:Możesz również użyć go jako dekoratora (od 2.6; ten przykład pochodzi z dokumentacji):
Jeśli chcesz, aby było to specyficzne
KeyboardInterrupt
tylko dla, odpowiedź innej osoby na to pytanie jest prawdopodobnie lepsza.Należy jednak pamiętać, że
atexit
moduł zawiera tylko ~ 70 linii kodu i nie byłoby trudno stworzyć podobną wersję, która traktuje wyjątki inaczej, na przykład przekazując wyjątki jako argumenty do funkcji wywołania zwrotnego. (Ograniczenieatexit
to gwarantowałoby zmodyfikowaną wersję: obecnie nie mogę sobie wyobrazić sposobu, w jaki funkcje wywołania zwrotnego wyjścia miałyby wiedzieć o wyjątkach; programatexit
obsługi przechwytuje wyjątek, wywołuje wywołanie zwrotne, a następnie ponownie wywołuje ten wyjątek. Ale możesz zrobić to inaczej).Więcej informacji:
atexit
źródło
atexit
działa zarówno dla MacOS, jak i Ubuntu 18.04 dla Pythona 3.7 i 3.8Możesz zapobiec drukowaniu śladu stosu
KeyboardInterrupt
beztry: ... except KeyboardInterrupt: pass
(najbardziej oczywistego i prawdopodobnie „najlepszego” rozwiązania, ale już go znasz i prosiłeś o coś innego), zastępującsys.excepthook
. Coś jakźródło
Wypróbowałem sugerowane rozwiązania przez wszystkich, ale musiałem sam improwizować kod, aby faktycznie zadziałał. Oto mój improwizowany kod:
źródło
Jeśli ktoś szuka szybkiego, minimalnego rozwiązania,
źródło