¿Cómo detectar múltiples excepciones en una línea? (en el bloque "excepto")

Resuelto inspectorG4dget asked hace 13 años • 6 respuestas

Sé que puedo hacer:

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

También puedo hacer esto:

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

Pero si quiero hacer lo mismo dentro de dos excepciones diferentes, lo mejor que se me ocurre ahora es hacer esto:

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

¿Hay alguna manera de que pueda hacer algo como esto (ya que la acción a realizar en ambas excepciones es say please):

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

Ahora bien, esto realmente no funcionará, ya que coincide con la sintaxis de:

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

Por lo tanto, mi esfuerzo por detectar las dos excepciones distintas no se materializa exactamente.

¿Hay alguna forma de hacer esto?

inspectorG4dget avatar Jun 24 '11 22:06 inspectorG4dget
Aceptado

De la documentación de Python :

Una cláusula de excepción puede nombrar múltiples excepciones como una tupla entre paréntesis, por ejemplo

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

O, solo para Python 2:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

Separar la excepción de la variable con una coma seguirá funcionando en Python 2.6 y 2.7, pero ahora está en desuso y no funciona en Python 3; ahora deberías estar usando as.

mechanical_meat avatar Jun 24 '2011 15:06 mechanical_meat

¿Cómo puedo detectar múltiples excepciones en una línea (excepto bloque)?

Hacer esto:

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

Los paréntesis son necesarios debido a la sintaxis anterior que usaba comas para asignar el objeto de error a un nombre. La aspalabra clave se utiliza para la tarea. Puede utilizar cualquier nombre para el objeto de error, yo errorpersonalmente lo prefiero.

Mejores prácticas

Para hacer esto de una manera compatible actualmente y en el futuro con Python, debe separar las Excepciones con comas y envolverlas entre paréntesis para diferenciarlas de la sintaxis anterior que asignaba la instancia de excepción a un nombre de variable siguiendo el tipo de excepción que se detectará con un coma.

A continuación se muestra un ejemplo de uso sencillo:

import sys

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
    sys.exit(0)

Estoy especificando solo estas excepciones para evitar ocultar errores, que si los encuentro espero obtener el seguimiento completo de la pila.

Esto está documentado aquí: https://docs.python.org/tutorial/errors.html

Puede asignar la excepción a una variable ( ees común, pero es posible que prefiera una variable más detallada si tiene un manejo de excepciones prolongado o si su IDE solo resalta selecciones más grandes que eso, como lo hace el mío). La instancia tiene un atributo args. Aquí hay un ejemplo:

import sys

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

Tenga en cuenta que en Python 3, el errobjeto queda fuera de alcance cuando exceptconcluye el bloque.

Obsoleto

Es posible que vea un código que asigna el error con una coma. Este uso, el único formulario disponible en Python 2.5 y versiones anteriores, está obsoleto y si desea que su código sea compatible con Python 3, debe actualizar la sintaxis para usar el nuevo formulario:

import sys

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

Si ve la asignación del nombre de coma en su código base y está usando Python 2.5 o superior, cambie a la nueva forma de hacerlo para que su código siga siendo compatible cuando actualice.

El suppressadministrador de contexto

La respuesta aceptada es en realidad 4 líneas de código, mínimo:

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

Las líneas try, except, passse pueden manejar en una sola línea con el administrador de contexto de supresión, disponible en Python 3.4 :

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

Entonces, cuando quieras passen ciertas excepciones, usa suppress.

Russia Must Remove Putin avatar Jun 21 '2014 04:06 Russia Must Remove Putin

De la documentación de Python -> 8.3 Manejo de excepciones :

Una trydeclaración puede tener más de una cláusula excepto, para especificar controladores para diferentes excepciones. Se ejecutará como máximo un controlador. Los controladores solo manejan excepciones que ocurren en la cláusula try correspondiente, no en otros controladores de la misma declaración try. Una cláusula de excepción puede nombrar múltiples excepciones como una tupla entre paréntesis, por ejemplo:

except (RuntimeError, TypeError, NameError):
    pass

Tenga en cuenta que los paréntesis alrededor de esta tupla son obligatorios, porque except ValueError, e:era la sintaxis utilizada para lo que normalmente se escribe except ValueError as e:en Python moderno (que se describe a continuación). La sintaxis anterior todavía se admite por compatibilidad con versiones anteriores. Este medio except RuntimeError, TypeErrorno equivale a except (RuntimeError, TypeError):pero a except RuntimeError as TypeError:cual no es lo que quieres.

fedorqui avatar Oct 30 '2014 10:10 fedorqui

Si utiliza con frecuencia una gran cantidad de excepciones, puede predefinir una tupla, para no tener que volver a escribirlas muchas veces.

#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

NOTAS:

  1. Si también necesita detectar otras excepciones además de las de la tupla predefinida, deberá definir otro bloque excepto.

  2. Si simplemente no puede tolerar una variable global, defínala en main() y pásela donde sea necesario...

whitebeard avatar Sep 18 '2017 01:09 whitebeard