2016-02-23 12 views
8

Wszystkie docs powiedzieć nam to,Kiedy w Punkcie Pytań podniesiono KeyboardInterrupt?

Raised gdy użytkownik wciśnie klawisz przerwania (zwykle Control-C lub Delete). Podczas wykonywania, kontrola przerwania jest wykonywana regularnie.

Ale od od punktu kodu, kiedy mogę zobaczyć ten wyjątek? Czy występuje podczas wykonywania instrukcji? Tylko między wypowiedziami? Czy może się to zdarzyć w trakcie wypowiedzi?

Na przykład:

file_ = open('foo') 
# <-- can a KeyboardInterrupt be raised here, after the successful 
# completion of open but prior to the try? --> 
try: 
    # try some things with file_ 
finally: 
    # cleanup 

Czy ten wyciek kodu podczas dokładnego KeyboardInterrupt? Czy jest on poruszany podczas wykonywania niektórych wypowiedzi lub wyrażeń?

Odpowiedz

1

Tak, KeyboardInterrupt może wystąpić w miejscu, które zaznaczyłeś.

Aby poradzić sobie z tym, należy użyć with bloku:

with open('foo') as file_: 
    # do some things 
    raise KeyboardInterrupt 

# file resource is closed no matter what, even if a KeyboardInterrupt is raised 

jednak wyjątek może wystąpić nawet między wywołania open() i przypisania do file_. Prawdopodobnie nie warto się tym martwić, ponieważ zwykle ctrl-c będzie oznaczało, że twój program się kończy, więc "wyciekany" uchwyt pliku zostanie wyczyszczony przez system operacyjny. Ale jeśli wiesz, że to jest ważne, możesz użyć a signal handler, aby złapać sygnał, który podnosi KeyboardInterrupt (SIGINT).

+0

Niestety, 'with' nie zawsze jest możliwe; czasami chcesz sprawdzić, czy wyrażenie w instrukcji with nie powiedzie się (np. czy podniosło konkretną eksplorację?) przed wywołaniem '__enter__'. Nie można tego zrobić za pomocą 'with', ponieważ tracisz zdolność do zawijania wyrażenia bez owijania ciała' with'. (Które, jeśli może wywołać ten sam typ wyjątku, co wyrażenie warunkowe, oznacza, że ​​nie można ich odróżnić w 'wyjściu'.) – Thanatos

4

Według notatki w niepowiązanych PEP 343:

Nawet jeśli piszesz wolna od błędów kod, na KeyboardInterrupt Wyjątkiem może jeszcze spowodować, aby wyjść między dowolnymi dwoma wirtualnymi rozkazy maszynowe.

Tak więc może wystąpić zasadniczo w dowolnym miejscu. Może rzeczywiście wystąpić podczas oceny pojedynczego wyrażenia. (To nie powinno dziwić, ponieważ wyrażenie może zawierać wywołania funkcji i prawie wszystko może się zdarzyć w wywołaniu funkcji.)