2012-01-26 14 views
6

piszę trochę kodu w Pythonie coś takiego:W języku Python, czy mogę zapobiec przechwyceniu funkcji KeyboardInterrupt i SystemExit?

import sys 
try: 
    for x in large_list: 
     function_that_catches_KeyboardInterrupt(x) 
except KeyboardInterrupt: 
    print "Canceled!" 
    sys.exit(1) 

Kiedy próbuję przerwać pętlę, ja w zasadzie trzeba przytrzymać Kontroli + C wystarczająco długo, aby anulować każde wywołanie funkcji dla wszystkich elementów large-list, a dopiero potem mój program zakończy działanie.

Czy jest jakiś sposób, żebym mógł uniemożliwić funkcję przechwytywania Klawiatury Przerwać, aby samemu ją przechwycić? Jedynym sposobem, jaki mogę wymyślić jest nadużywanie wątków poprzez tworzenie oddzielnego wątku tylko dla wywołania funkcji, ale wydaje się to przesadne.

Edycja: Sprawdziłem kod naruszający prawa (którego nie mogę łatwo zmienić), a on faktycznie używa gołego except:, więc nawet sys.exit(1) został złapany jako wyjątek SystemExit. Jak mogę uciec z pustego bloku except: i zamknąć program?

+0

Nie wydaje mi się to zbytnim przesadnym ... także dlatego, że każde inne rozwiązanie, jakie wymyślę, wiązałoby się z pewnym rodzajem czerni magic ... – GaretJax

+0

Pamiętaj, że nie musisz używać nici do każdego wywołania, wystarczy tylko jeden. ;-) – GaretJax

Odpowiedz

6

Można ponownie powiązać procedurę obsługi SIGINT przy użyciu biblioteki signal.

import signal, sys 
def handler(signal, frame): 
    print "Canceled!" 
    sys.exit(1) 
signal.signal(signal.SIGINT, handler) 
for x in large_list: 
    function_that_catches_KeyboardInterrupt(x) 

Istnieje kilka sposobów, w jaki można wyjść, gdy zostanie przechwycony SystemExit. os._exit(1) zrobi wyjście w stylu c bez czyszczenia. os.kill(os.getpid(), signal.SIGTERM) pozwoli interpreterowi na pewien poziom oczyszczenia, myślę, że płukanie/zamykanie uchwytów plików, itp.

+0

Myślę, że on chce, aby sygnał został przechwycony przez zewnętrzny wyjątek - po prostu nie przez kod wewnątrz funkcji. To tłumi to całkowicie –

+0

Następnie może zastąpić wywołanie sys.exit czymś, co kontroluje dłonie z powrotem do swojego programu. Masz już do czynienia z porwaniem kontroli przepływu, nie sądzę, że zamierzasz znaleźć bardziej eleganckie rozwiązanie;) – stefan

+0

Czy mogę po prostu zamienić 'sys.exit' na' raise KeyboardInterrupt() '? A może powinienem użyć innego wyjątku? –

Powiązane problemy