2010-10-14 13 views
29

Si consideri il seguente codice:Cosa fa raise in Python?

try: 
    raise Exception("a") 
except: 
    try: 
     raise Exception("b") 
    finally: 
     raise 

Ciò consentirà di aumentare Exception: a. Mi aspettavo che aumentasse Exception: b (ho bisogno di spiegarmi perché?). Perché l'ultimo raise genera l'eccezione originale anziché (cosa pensavo) era l'ultima eccezione sollevata?

+7

Python 3.1 solleva entrambi. – kennytm

+1

Ah. Avrei dovuto dire che sono su Python 2.6. – wilhelmtell

+1

Solo per curiosità: il compilatore C# sulla stessa combinazione dice "Errore: un'istruzione throw senza argomenti non è consentita in una clausola finally che è annidata all'interno della clausola catch più vicina" (throw == raise, catch == tranne). Nessuna ambiguità! – Andrey

risposta

15

Su python2.6

immagino, vi aspettate il blocco finally di essere legato con il blocco "provare" in cui si alza l'eccezione "B". Il blocco finally è collegato al primo blocco "try".

Se è stato aggiunto un blocco tranne nel blocco try interna, poi il blocco finally solleverà eccezione B.

try: 
    raise Exception("a") 
except: 
    try: 
    raise Exception("b") 
    except: 
    pass 
    finally: 
    raise 

uscita:

Traceback (most recent call last): 
    File "test.py", line 5, in <module> 
    raise Exception("b") 
Exception: b 

Un'altra variazione che spiega che cosa sta accadendo qui

try: 
    raise Exception("a") 
except: 
    try: 
    raise Exception("b") 
    except: 
    raise 

Uscita:

Traceback (most recent call last): 
    File "test.py", line 7, in <module> 
    raise Exception("b") 
Exception: b 

Se si vede qui, sostituendo il blocco finally con eccezione solleva l'eccezione B.

+0

Sono giunto alla stessa conclusione. –

+0

Infatti, questo funziona! Non avrei mai immaginato. Questo è documentato da qualche parte? È una caratteristica o è una necessità che deriva da problemi grammaticali? – wilhelmtell

+0

Perché la seconda eccezione non fa semplicemente ombra al primo? Vorrei che Python si sbagliasse per la sintassi, o almeno mi avvisasse di questo. – wilhelmtell

26

Raise is re-raising the last exception you caught, not the last exception you raised

(ripubblicato da commenti per chiarezza)