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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top