2010-01-21 6 views
11

ho qualche codice in un except clausola di Python che è destinato a fare un po 'di registrazione, ma il codice di registrazione può causare in sé un'eccezione. Nel mio caso, vorrei semplicemente ignorare qualsiasi seconda eccezione che potrebbe verificarsi e sollevare l'eccezione originale. Ecco un esempio molto semplificato:Gestione un'eccezione Python che si verifica all'interno di una clausola except

try: 
    a = this_variable_doesnt_exist 
except: 
    try: 
     1/0 
    except: 
     pass 
    raise 

L'esecuzione del codice di cui sopra, spero di ottenere:

NameError: name 'this_variable_doesnt_exist' is not defined 

ma invece, in Python 2.x, ottengo:

ZeroDivisionError: integer division or modulo by zero 

Ho scoperto che in Python 3.x, fa quello che voglio.

Non ho trovato molti commenti su questo nei documenti Python 2.x (a meno che non lo avessi perso). Posso ottenere questo in 2.x?

risposta

15

con l'astrazione:

def log_it(): 
    try: 
     1/0 
    except: 
     pass 

try: 
    this = that 
except: 
    log_it() 
    raise 

fa quello che vuoi in Python 2.5

Un altro modo per farlo è quello di memorizzare l'eccezione in una variabile, poi ri-sollevare esplicitamente:

try: 
    this = that 
except NameError, e: # or NameError as e for Python 2.6 
    try: 
     1/0 
    except: 
     pass 
    raise e 

noti che probabilmente non dovrebbe solo utilizzare un nudo except per catturare tutto ciò che potrebbe venire - di solito è meglio per catturare le eccezioni specifiche che ci si aspetta t o si verificano nel caso in cui si verifichi un'eccezione drastica e fatale (come l'esaurimento della memoria).

18

Credo che quello che stai vedendo sia il risultato di exception chaining, che è un change in Python 3.

Dal motivazione sezione della PEP:

Durante lo spostamento della sola eccezione (eccezione A), è possibile che si verifichi un nuovo eccezione (eccezione B). In Python di oggi (versione 2.4), se ciò accade, l'eccezione B viene propagata all'esterno e l'eccezione A viene persa. Per eseguire il debug del problema, è utile conoscere entrambe le eccezioni. L'attributo __context__ conserva queste informazioni automaticamente.

Il PEP va quindi a descrivere il nuovo concatenamento eccezione (che viene realizzato in Py3k) in dettaglio — è una lettura interessante. Ho imparato qualcosa di nuovo oggi.

+0

come si dovrebbe gestire esplicitamente l'eccezione secondaria? Si prega di includere questo nella vostra risposta –

0

Nel mio CausedException class mi prendo cura di quello per Python 2.x (e anche per Python 3, nel caso in cui si voglia passare a causa di alberi invece di semplici catene di cause). Forse può aiutarti.

+1

Mentre questo può teoricamente rispondere alla domanda, [sarebbe preferibile] (http://meta.stackexchange.com/q/8259) per includere le parti essenziali del risposta qui, e fornire il link per riferimento. –

Problemi correlati