2013-07-25 9 views
5

Vorrei rilevare un'eccezione specifica e gestirla di conseguenza, quindi vorrei continuare ed eseguire la gestione generica che altre eccezioni dovrebbero avere.Gestione di eccezioni Python specifiche e generali?

Provenendo da uno sfondo C, in precedenza avrei potuto utilizzare gotos per ottenere l'effetto desiderato.

Questo è quello che sto facendo attualmente è e funziona benissimo:

try: 
    output_var = some_magical_function() 
except IntegrityError as zde: 
    integrity_error_handling() 
    shared_exception_handling_function(zde) # could be error reporting 
except SomeOtherException as soe: 
    shared_exception_handling_function(soe) # the same function as above 

TLDR:

Ie - C'è modo "Pythonic" di fare quanto segue:

try: 
    output_var = some_magical_function() 
except IntegrityError as zde: 
    integrity_error_handling() 
except ALLExceptions as ae: # all exceptions INCLUDING the IntregityError 
    shared_exception_handling_function(ae) # could be error reporting 

NB: Sono a conoscenza della clausola finally - non è intesa per l'ordine (cioè per la chiusura di file) ·

+0

Sfortunatamente in Python non ci sono le tecniche "casuali" per "sfuggire" a certe eccezioni, ma per costruire una struttura "try..except" in cascata per gestire specifiche in inner, quindi passare a outer per la gestione generale. – woozyking

risposta

10

Si potrebbe reraise l'eccezione, e gestire il caso generica nel gestore esterno di una configurazione annidata:

try: 
    try: 
     output_var = some_magical_function() 
    except IntegrityError as zde: 
     integrity_error_handling() 
     raise 
except ALLExceptions as ae: # all exceptions INCLUDING the IntregityError 
    shared_exception_handling_function(ae) # could be error reporting 

Non Qualificato raise dichiarazione ri-solleva l'eccezione corrente, quindi l'eccezione IntegrityError è gettato ancora una volta di essere gestito dal gestore AllExceptions.

L'altro percorso si può prendere è quello di testare per il tipo di eccezione:

try: 
    output_var = some_magical_function() 
except ALLExceptions as ae: # all exceptions INCLUDING the IntregityError 
    if isinstance(ae, IntegrityError): 
     integrity_error_handling() 
    shared_exception_handling_function(ae) # could be error reporting 
+0

Il secondo approccio sarebbe appropriato per alcune librerie con un pool di errori specifici che eredita la stessa eccezione genitore. Il primo è più adatto quando la generalizzazione è più difficile da fare. La combinazione di entrambi è quasi a prova di proiettile ma ancora elegante/Pythonic, imho. – woozyking

+0

@woozyking: Ma per 'ALLExceptions' per catturare' IntegrityError', * deve * essere una classe base per quest'ultimo. –

+0

Infatti. Presumo che molte persone inizieranno con la creazione di sottoclassi al generico 'Exception' e poi lavoreranno all'astrazione di livello medio quando necessario. – woozyking

4

La classe Exception corrisponderà tutte le eccezioni ...

try: 
    output_var = some_magical_function() 
except IntegrityError as zde: 
    integrity_error_handling() 
except Exception as ae: 
    shared_exception_handling_function(ae) # could be error reporting 

Ma sembra che si vuole la finale clausola da eseguire sia per le eccezioni IntegrityError che per tutto il resto. Quindi, avrete bisogno di un costrutto diverso, forse questo:

try: 
    try: 
     output_var = some_magical_function() 
    except IntegrityError as zde: 
     integrity_error_handling() 
     raise 
except Exception as ae: 
    shared_exception_handling_function(ae) # could be error reporting 

Il comando raise su quello interno try ... except blocco fa sì che il eccezione intercettata da passare fino al blocco esterno.

+0

'Exception' corrisponde a tutte le eccezioni built-in che non portano all'uscita del sistema. –