2016-02-23 21 views
8

Tutti i documenti ci dicono è,Quando viene sollevato KeyboardInterrupt in Python?

sollevata quando l'utente preme il tasto di interruzione (normalmente Control-C o Delete). Durante l'esecuzione, viene effettuato regolarmente un controllo per gli interrupt.

Ma dal punto del codice, quando posso vedere questa eccezione? Si verifica durante l'esecuzione dell'istruzione? Solo tra dichiarazioni? Può accadere nel mezzo di un'espressione?

Ad esempio:

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 

Sarà questa perdita di codice nel corso di una tempestiva KeyboardInterrupt? O è sollevato durante l'esecuzione di alcune dichiarazioni o espressioni?

risposta

1

Sì, uno KeyboardInterrupt si può verificare nel posto contrassegnato.

Per far fronte a questo, è necessario utilizzare un blocco with:

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

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

Tuttavia, potrebbe verificarsi l'eccezione, anche tra la open() chiamata e l'incarico di file_. Probabilmente non vale la pena preoccuparsi di questo, perché solitamente un ctrl-c significa che il programma sta per terminare, quindi l'handle del file "trapelato" verrà ripulito dal sistema operativo. Ma se sai che è importante, puoi usare a signal handler per prendere il segnale che solleva KeyboardInterrupt (SIGINT).

+0

Sfortunatamente, un 'with' non è sempre possibile; a volte vuoi vedere se l'espressione nell'istruzione with fallisce (ad es. ha sollevato una particolare expcetion?) prima di chiamare '__enter__'. Non puoi farlo con 'with', perché perdi la capacità di avvolgere l'espressione senza avvolgere il corpo di' with'. (Che, se può generare lo stesso tipo di eccezione di with-expression, significa che non puoi distinguerli nel tuo 'except'.) – Thanatos

4

Secondo una nota nella estranei PEP 343:

Anche se si scrive codice privo di bug, un'eccezione KeyboardInterrupt può ancora causare a uscire tra due codici operativi delle macchine virtuali.

Quindi può verificarsi essenzialmente ovunque. Può effettivamente verificarsi durante la valutazione di una singola espressione. (Questo non dovrebbe sorprendere, dal momento che un'espressione può includere chiamate di funzione e praticamente qualsiasi cosa può accadere all'interno di una chiamata di funzione.)