Domanda Cattura più eccezioni in una riga (eccetto il blocco)


So che posso fare:

try:
    # do something that may fail
except:
    # do this if ANYTHING goes wrong

Posso anche fare questo:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreTooShortException:
    # stand on a ladder

Ma se voglio fare la stessa cosa in due diverse eccezioni, il meglio che posso pensare adesso è quello di fare questo:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreBeingMeanException:
    # say please

C'è un modo in cui posso fare qualcosa di simile (dal momento che l'azione da intraprendere in entrambe le eccezioni è say please):

try:
    # do something that may fail
except IDontLikeYouException, YouAreBeingMeanException:
    # say please

Ora questo davvero non funzionerà, poiché corrisponde alla sintassi per:

try:
    # do something that may fail
except Exception, e:
    # say please

Quindi, il mio tentativo di cogliere le due distinte eccezioni non viene esattamente raggiunto.

C'è un modo per fare questo?


1957
2018-06-24 15:55


origine


risposte:


A partire dal Documentazione Python:

Una clausola except può nominare più eccezioni come una tupla tra parentesi, per esempio

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

Oppure, solo per Python 2:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

Separare l'eccezione dalla variabile con una virgola funzionerà ancora in Python 2.6 e 2.7, ma ora è deprecato e non funziona in Python 3; ora dovresti usare as.


2696
2018-06-24 15:56



Come faccio a catturare più eccezioni in una riga (eccetto il blocco)

Fai questo:

try:
    may_raise_specific_errors():
except (SpecificErrorOne, SpecificErrorTwo) as error:
    handle(error) # might log or have some other default behavior...

Le parentesi sono obbligatorie a causa della sintassi più vecchia che utilizzava le virgole per assegnare l'oggetto errore a un nome. Il as la parola chiave viene utilizzata per il compito. Puoi usare qualsiasi nome per l'oggetto error, preferisco error personalmente.

La migliore pratica

Per farlo in un modo correntemente compatibile con Python, devi separare le Eccezioni con le virgole e avvolgerle con parentesi per differenziare dalla sintassi precedente che ha assegnato l'istanza di eccezione a un nome di variabile seguendo il tipo di Eccezione da catturare con un virgola.

Ecco un esempio di utilizzo semplice:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
    quit(0)

Sto specificando solo queste eccezioni per evitare di nascondere i bachi, che se incontro mi aspetto che la traccia dello stack completo provenga.

Questo è documentato qui: https://docs.python.org/tutorial/errors.html

È possibile assegnare l'eccezione a una variabile, (e è comune, ma potresti preferire una variabile più dettagliata se hai una gestione delle eccezioni lunga o il tuo IDE evidenzia solo selezioni più grandi di quelle, come fa la mia.) L'istanza ha un attributo args. Ecco un esempio:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError) as err: 
    print(err)
    print(err.args)
    quit(0)

Si noti che in Python 3, il err oggetto cade fuori campo quando il except il blocco è concluso.

deprecato

Potresti visualizzare il codice che assegna l'errore con una virgola. Questo utilizzo, l'unico modulo disponibile in Python 2.5 e versioni precedenti, è deprecato e, se si desidera che il codice sia compatibile con forward in Python 3, è necessario aggiornare la sintassi per utilizzare il nuovo modulo:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+
    print err
    print err.args
    quit(0)

Se vedi l'assegnazione del nome virgola nella tua base di codice e stai usando Python 2.5 o versioni successive, passa al nuovo modo di farlo in modo che il tuo codice rimanga compatibile quando esegui l'upgrade.

Il suppress gestore del contesto

La risposta accettata è in realtà 4 righe di codice, minimo:

try:
    do_something()
except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

Il try, except, pass le linee possono essere gestite in una sola riga con il sopprimere il gestore di contesto, disponibile in Python 3.4:

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

Quindi quando vuoi pass su alcune eccezioni, utilizzare suppress.


184
2018-06-21 04:20



Per python 2.5 e versioni precedenti, la sintassi corretta è:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    print e

Dove e è l'istanza Exception.


49
2018-05-13 12:37



A partire dal Documentazione su Python -> 8.3 Gestione delle eccezioni:

UN try la dichiarazione può avere più di una clausola except, per specificare   gestori per diverse eccezioni. Al massimo un handler sarà   eseguito. I gestori gestiscono solo le eccezioni che si verificano nel file   corrispondente clausola di prova, non in altri gestori della stessa prova   dichiarazione. Una clausola except può nominare più eccezioni come a   tuple parentesi, ad esempio:

except (RuntimeError, TypeError, NameError):
    pass

Nota che le parentesi attorno a questa tupla sono obbligatorie, perché   tranne ValueError, e: era la sintassi usata per ciò che è normalmente   scritto come except ValueError as e: nel moderno Python (descritto   sotto). La vecchia sintassi è ancora supportata per la compatibilità all'indietro.   Questo significa except RuntimeError, TypeError non è equivalente a    except (RuntimeError, TypeError): ma a except RuntimeError as TypeError: che non è quello che vuoi


37
2017-10-30 10:01



Se utilizzi spesso un numero elevato di eccezioni, puoi definire una tupla, quindi non devi ridigitarle più volte.

#This example code is a technique I use in a library that connects with websites to gather data

ConnectErrs  = (URLError, SSLError, SocketTimeoutError, BadStatusLine, ConnectionResetError)

def connect(url, data):
    #do connection and return some data
    return(received_data)

def some_function(var_a, var_b, ...):
    try: o = connect(url, data)
    except ConnectErrs as e:
        #do the recovery stuff
    blah #do normal stuff you would do if no exception occurred

GLI APPUNTI: 

  1. Se anche tu hai bisogno di prendere altre eccezioni rispetto a quelle nella tupla predefinita, dovrai definirne un'altra ad eccezione del blocco.

  2. Se non riesci a tollerare una variabile globale, definiscila in main () e passatelo dove necessario ...


15
2017-09-18 01:36



Uno dei modi per farlo è ..

try:
   You do your operations here;
   ......................
except(Exception1[, Exception2[,...ExceptionN]]]):
   If there is any exception from the given exception list, 
   then execute this block.
   ......................
else:
   If there is no exception then execute this block. 

e un altro modo è creare un metodo che esegua un compito eseguito da except bloccalo e chiamalo attraverso tutto il except blocco che scrivi ..

try:
   You do your operations here;
   ......................
except Exception1:
    functionname(parameterList)
except Exception2:
    functionname(parameterList)
except Exception3:
    functionname(parameterList)
else:
   If there is no exception then execute this block. 

def functionname( parameters ):
   //your task..
   return [expression]

So che il secondo non è il modo migliore per farlo, ma sto solo mostrando un numero di modi per fare questa cosa.


5
2017-08-17 11:56



La documentazione di Python 2.7 afferma che:

Una dichiarazione try può avere più di una clausola except, per specificare   gestori per diverse eccezioni. Al massimo un handler sarà   eseguito. I gestori gestiscono solo le eccezioni che si verificano nel file   corrispondente clausola di prova, non in altri gestori della stessa prova   dichiarazione. Una clausola except può nominare più eccezioni come a   tuple parentesi, ad esempio:

try:
    raise ValueError("hello")
except (RuntimeError, ValueError, KeyError) as a:
    print a

Nota   che le parentesi attorno a questa tupla sono obbligatorie, perché eccetto   ValueError, e: era la sintassi utilizzata per ciò che è normalmente scritto come   ad eccezione di ValueError as e: in Python moderno (descritto di seguito). La vecchia   la sintassi è ancora supportata per la compatibilità all'indietro. Questo significa   tranne RuntimeError, TypeError non è equivalente ad eccezione di   (RuntimeError, TypeError): ma ad eccezione di RuntimeError come TypeError:   che non è quello che vuoi


3
2017-12-05 14:05