2015-03-26 6 views
7

Ho il seguente codice:Python 3 eccezione elimina variabile allegando possibilità di sconosciuto motivo

def foo(): 
    e = None 
    try: 
     raise Exception('I wish you would except me for who I am.') 
    except Exception as e: 
     print(e) 
    print(e) 

foo() 

In Python 2.7, questo viene eseguito come stampe attesi e:

I wish you would except me for who I am. 
I wish you would except me for who I am. 

Tuttavia in Python 3. x, viene stampata la prima riga, ma la seconda non lo è. Sembra di eliminare la variabile nel campo di applicazione che racchiude, dandomi il seguente traceback dall'ultima istruzione print:

Traceback (most recent call last): 
    File "python", line 9, in <module> 
    File "python", line 7, in foo 
UnboundLocalError: local variable 'e' referenced before assignment 

E 'quasi come se si inserisce una dichiarazione del e dopo il blocco except. C'è qualche ragionamento per questo tipo di comportamento? Potrei capire se gli sviluppatori Python volevano che i blocchi avessero il loro ambito locale e non trapelassero nell'ambiente circostante, ma perché deve eliminare una variabile nello scope esterno che era stata precedentemente assegnata?

+3

https://www.python.org/dev/peps/pep-3110/ e https://www.python.org/dev/peps/pep-0344/aiuterà. –

risposta

11

citando i documentation of try,

Quando un'eccezione è stato assegnato attraverso as target, esso viene azzerato alla fine della clausola except. Questo è come se

except E as N: 
    foo 

stato tradotto a

except E as N: 
    try: 
     foo 
    finally: 
     del N 

Ciò significa che l'eccezione deve essere assegnato a un nome diverso per poter fare riferimento ad essa dopo la clausola except. Le eccezioni vengono cancellate perché con il traceback ad esse collegato, formano un ciclo di riferimento con il frame dello stack, mantenendo attivi tutti i locals in quel frame fino al successivo garbage collection.

Questo è coperto in questi due PEP.

  1. PEP 3110 - Catching Exceptions in Python 3000

  2. PEP 344 - Exception Chaining and Embedded Tracebacks