Sto scrivendo codice Python 2.6.6 su Windows che assomiglia a questo:Perché non riesco a gestire un KeyboardInterrupt in python?
try:
dostuff()
except KeyboardInterrupt:
print "Interrupted!"
except:
print "Some other exception?"
finally:
print "cleaning up...."
print "done."
dostuff()
è una funzione che loop per sempre, la lettura di una linea alla volta da un flusso di input e di agire su di esso. Voglio essere in grado di fermarlo e ripulire quando premo ctrl-c.
Quello che succede invece è che il codice sotto except KeyboardInterrupt:
non funziona affatto. L'unica cosa che viene stampato è "pulendo ...", e poi un traceback viene stampato che assomiglia a questo:
Traceback (most recent call last):
File "filename.py", line 119, in <module>
print 'cleaning up...'
KeyboardInterrupt
Quindi, il codice di gestione delle eccezioni non è in esecuzione, e il traceback sostiene che un KeyboardInterrupt si è verificato durante la clausola finale, che non ha senso perché battere ctrl-c è ciò che ha causato quella parte da eseguire in primo luogo! Anche la clausola generica except:
non è in esecuzione.
MODIFICA: In base ai commenti, ho sostituito il contenuto del blocco try:
con sys.stdin.read(). Il problema si verifica ancora esattamente come descritto, con la prima riga del blocco finally:
in esecuzione e quindi la stampa dello stesso traceback.
MODIFICA # 2: Se aggiungo praticamente qualsiasi cosa dopo la lettura, il gestore funziona. Quindi, questo non funziona:
try:
sys.stdin.read()
except KeyboardInterrupt:
...
Ma questo funziona:
try:
sys.stdin.read()
print "Done reading."
except KeyboardInterrupt:
...
Ecco cosa c'è stampato: "finito di leggere"
Done reading. Interrupted!
cleaning up...
done.
Così, per qualche motivo, la la linea viene stampata, anche se l'eccezione si è verificata sulla riga precedente. Questo non è davvero un problema - ovviamente devo essere in grado di gestire un'eccezione ovunque all'interno del blocco "prova". Tuttavia, la stampa non funziona normalmente - non stampa successivamente una nuova riga come dovrebbe! Il "Interruped" è stampato sulla stessa linea ... con uno spazio prima, per qualche motivo ...? Comunque, dopo che il codice fa quello che dovrebbe.
Mi sembra che questo sia un bug nella gestione di un interrupt durante una chiamata di sistema bloccata.
Mostra il codice per il tuo dostuff(), perché questo codice dovrebbe funzionare (e lo fa) – user225312
Funziona come previsto con Python 2.5.1. – khachik
riprodotto con Python 2.7, sostituendo 'dostuff()' con 'sys.stdin.read()' – balpha