rafforzare l'eccezione di Python.Quale catturare?
Domanda
Sto imparando ad usare Python.Ho appena trovato questo articolo: http://mendbatchelder.com/blog/200711/rethrowing_exceptions_in_python.html Descrive le eccezioni ritornanti in Python, come questa:
try:
do_something_dangerous()
except:
do_something_to_apologize()
raise
.
Dal momento che ri-lancia l'eccezione, ci sarà una dichiarazione "esterna catch-tranne".Ma ora stavo pensando.Cosa succede se il do_something_to_apologize () all'interno eccetto il lancio di un errore.Quale sarà catturato nel "catch-tranne" esterno?Quello che ritorni o quello lanciato da do_something_to_apologize ()? O l'eccezione con la promozione più alta è catturata prima?
Soluzione
Provalo e guarda:
def failure():
raise ValueError, "Real error"
def apologize():
raise TypeError, "Apology error"
try:
failure()
except ValueError:
apologize()
raise
.
Il risultato:
Traceback (most recent call last):
File "<pyshell#14>", line 10, in <module>
apologize()
File "<pyshell#14>", line 5, in apologize
raise TypeError, "Apology error"
TypeError: Apology error
.
Il motivo: l'errore "reale" dalla funzione originale era già catturato dal except
. apologize
aumenta un nuovo errore prima che venga raggiunto il raise
. Pertanto, il raise
nella clausola except
non viene mai eseguito e solo l'errore delle scuse si propaga verso l'alto. Se apologize
aumenta un errore, Python non ha modo di sapere che avresti intenzione di aumentare un'eccezione diversa dopo apologize
.
Si noti che in Python 3, la traceback menzionerà entrambe le eccezioni , con un messaggio che spiega come è sorto il secondo:
Traceback (most recent call last):
File "./prog.py", line 9, in <module>
File "./prog.py", line 2, in failure
ValueError: Real error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "./prog.py", line 11, in <module>
File "./prog.py", line 5, in apologize
TypeError: Apology error
.
Tuttavia, la seconda eccezione (l'eccezione "scuse") è ancora l'unico che si propaga verso l'esterno e può essere catturato da una clausola except
di livello superiore. L'eccezione originale è menzionata nella traceback ma è soblita nel successivo e non può più essere catturata.
Altri suggerimenti
L'eccezione lanciata da do_something_to_apologize () sarà catturata.La linea contenente il rilancio non funzionerà mai, a causa dell'eccezione lanciata da do_something_to_apologize.Inoltre, non credo che ci sia un'idea di "priorità" nelle eccezioni di Python.