¿Por qué "except: pass" es una mala práctica de programación?

325

A menudo veo comentarios sobre otras preguntas de Stack Overflow sobre cómo except: passse desaconseja el uso de . ¿Por qué es esto malo? A veces simplemente no me importa cuáles son los errores, y solo quiero continuar con el código.

try:
    something
except:
    pass

¿Por qué es except: passmalo usar un bloque? ¿Qué lo hace malo? ¿Es el hecho de que estoy passen un error o que tengo exceptalgún error?

Vader
fuente
1
Por lo menos, te sugiero que lo registres, para que SABAS qué problemas estás ignorando. Use el loggingmódulo en el nivel DEBUG para evitar que se transmitan en producción, pero manténgalos disponibles en el desarrollo.
pcurry

Respuestas:

346

Como adivinó correctamente, tiene dos lados: detectar cualquier error al no especificar ningún tipo de excepción despuésexcept y simplemente pasarlo sin realizar ninguna acción.

Mi explicación es "un poco" más larga, así que, tl; dr se descompone en esto:

  1. No atrape ningún error . Siempre especifique de qué excepciones está preparado para recuperarse y solo capture esas.
  2. Trate de evitar pasar, excepto los bloques . A menos que se desee explícitamente, esto generalmente no es una buena señal.

Pero entremos en detalles:

No atrape ningún error

Cuando usa un trybloque, generalmente lo hace porque sabe que existe la posibilidad de que se produzca una excepción. Como tal, también tiene una idea aproximada de lo que se puede romper y qué excepción se puede lanzar. En tales casos, detecta una excepción porque puede recuperarse positivamente de ella. Eso significa que está preparado para la excepción y tiene algún plan alternativo que seguirá en caso de esa excepción.

Por ejemplo, cuando le pide al usuario que ingrese un número, puede convertir la entrada usando lo int()que podría elevar a ValueError. Puede recuperarlo fácilmente simplemente pidiéndole al usuario que lo intente nuevamente, por lo que atraparlo ValueErrory solicitarle nuevamente sería un plan apropiado. Un ejemplo diferente sería si desea leer alguna configuración de un archivo, y ese archivo no existe. Debido a que es un archivo de configuración, es posible que tenga alguna configuración predeterminada como respaldo, por lo que el archivo no es exactamente necesario. Por lo tanto, capturar FileNotFoundErrory simplemente aplicar la configuración predeterminada sería un buen plan aquí. Ahora, en ambos casos, tenemos una excepción muy específica que esperamos y tenemos un plan igualmente específico para recuperarnos de ella. Como tal, en cada caso, explícitamente solo except ese cierto excepción.

Sin embargo, si tuviéramos que atrapar todo , entonces, además de esas excepciones de las que estamos preparados para recuperarnos, también existe la posibilidad de que obtengamos excepciones que no esperábamos y de las cuales no podemos recuperarnos; o no debería recuperarse de.

Tomemos el ejemplo del archivo de configuración de arriba. En caso de que falte un archivo, simplemente aplicamos nuestra configuración predeterminada, y podríamos decidir en un momento posterior guardar automáticamente la configuración (por lo que la próxima vez, el archivo existe). Ahora imagina que tenemos un IsADirectoryError, o unPermissionErroren lugar. En tales casos, probablemente no queremos continuar; aún podríamos aplicar nuestra configuración predeterminada, pero luego no podremos guardar el archivo. Y es probable que el usuario también pretendiera tener una configuración personalizada, por lo que probablemente no se desee utilizar los valores predeterminados. Por lo tanto, nos gustaría informarle al usuario de inmediato, y probablemente también abortar la ejecución del programa. Pero eso no es algo que queremos hacer en algún lugar dentro de una pequeña parte del código; Esto es algo de importancia a nivel de aplicación, por lo que debe manejarse en la parte superior, así que deje que la excepción brote.

Otro ejemplo simple también se menciona en el documento de modismos de Python 2 . Aquí, existe un error tipográfico simple en el código que hace que se rompa. Debido a que estamos cogiendo cada excepción, que también capturan NameErrors y SyntaxErrors . Ambos son errores que nos ocurren a todos durante la programación; y ambos son errores que no queremos incluir al enviar el código. Pero debido a que también los detectamos, ni siquiera sabremos que ocurrieron allí y perdemos cualquier ayuda para depurarlo correctamente.

Pero también hay excepciones más peligrosas para las cuales no estamos preparados. Por ejemplo, SystemError suele ser algo que ocurre raramente y que realmente no podemos planificar; significa que está sucediendo algo más complicado, algo que probablemente nos impide continuar con la tarea actual.

En cualquier caso, es muy poco probable que esté preparado para todo en una parte del código a pequeña escala, por lo que es allí donde solo debería detectar las excepciones para las que está preparado. Algunas personas sugieren al menos atrapar, Exceptionya que no incluirá cosas como SystemExity KeyboardInterruptque, por diseño , terminarán su aplicación, pero diría que esto todavía es demasiado inespecífico. Solo hay un lugar donde personalmente acepto la captura Exceptiono cualquieraexcepción, y eso está en un único controlador de excepciones de nivel de aplicación global que tiene el único propósito de registrar cualquier excepción para la que no estábamos preparados. De esa manera, aún podemos retener tanta información sobre excepciones inesperadas, que luego podemos usar para extender nuestro código para manejarlas explícitamente (si podemos recuperarnos de ellas) o, en caso de un error, crear casos de prueba para asegurarnos No volverá a suceder. Pero, por supuesto, eso solo funciona si alguna vez detectamos las excepciones que ya estábamos esperando, por lo que las que no esperábamos surgirán naturalmente.

Trate de evitar pasar, excepto los bloques

Al capturar explícitamente una pequeña selección de excepciones específicas, hay muchas situaciones en las que estaremos bien simplemente no haciendo nada. En tales casos, solo tener except SomeSpecificException: passestá bien. Sin embargo, la mayoría de las veces, este no es el caso, ya que probablemente necesitemos algún código relacionado con el proceso de recuperación (como se mencionó anteriormente). Esto puede ser, por ejemplo, algo que vuelve a intentar la acción, o para configurar un valor predeterminado.

Sin embargo, si ese no es el caso, por ejemplo, porque nuestro código ya está estructurado para repetirse hasta que tenga éxito, simplemente pasar es suficiente. Tomando nuestro ejemplo de arriba, podríamos pedirle al usuario que ingrese un número. Como sabemos que a los usuarios no les gusta hacer lo que les pedimos, podríamos ponerlo en un bucle en primer lugar, para que se vea así:

def askForNumber ():
    while True:
        try:
            return int(input('Please enter a number: '))
        except ValueError:
            pass

Debido a que seguimos intentándolo hasta que no se produce ninguna excepción, no necesitamos hacer nada especial en el bloque excepto, por lo que está bien. Pero, por supuesto, uno podría argumentar que al menos queremos mostrarle al usuario algún mensaje de error para decirle por qué tiene que repetir la entrada.

Sin embargo, en muchos otros casos, el solo hecho de pasar exceptuna señal es una señal de que no estábamos realmente preparados para la excepción que estamos detectando. A menos que esas excepciones sean simples (como ValueErroro TypeError), y la razón por la que podemos aprobar es obvia, trate de evitarla. Si realmente no hay nada que hacer (y está absolutamente seguro de ello), considere agregar un comentario de por qué ese es el caso; de lo contrario, expanda el bloque excepto para incluir algún código de recuperación.

except: pass

Sin embargo, el peor delincuente es la combinación de ambos. Esto significa que estamos captando cualquier error voluntariamente, aunque no estamos absolutamente preparados para ello y tampoco hacemos nada al respecto. Usted al menos desea registrar el error y también es probable que vuelves a subir todavía para terminar la aplicación (que es poco probable que pueda continuar de manera normal después de un MemoryError). Sin embargo, el simple hecho de pasar no solo mantendrá la aplicación un tanto activa (dependiendo de dónde se encuentre, por supuesto), sino que también arrojará toda la información, lo que hará imposible descubrir el error, lo cual es especialmente cierto si usted no es el que lo descubre.


Entonces, la conclusión es: Capture solo las excepciones que realmente espera y está preparado para recuperarse; todos los demás probablemente sean errores que debe corregir o algo para lo que no está preparado de todos modos. Pasar excepciones específicas está bien si realmente no necesita hacer algo al respecto. En todos los demás casos, es solo un signo de presunción y de ser flojo. Y definitivamente quieres arreglar eso.

dar un toque
fuente
1
"Al menos quieres registrar el error y también es probable que lo vuelvas a subir para terminar la aplicación". ¿Puede demostrar cómo "volver a plantear" una excepción para dejar que continúe burbujeando incluso después de atraparla? Esto me parece útil para agregar algunos mensajes de error personalizados sin dejar que la excepción obligue a la aplicación a cerrar.
Gabriel Staples
1
Esto ayuda a aclarar: usan la manta except, pero luego llaman raisesin argumentos para continuar dejando que la excepción brote, terminando la aplicación. Me gusta: ianbicking.org/blog/2007/09/re-raising-exceptions.html . Parece una excepción sólida a la regla sobre no usar la manta except.
Gabriel Staples
1
@GabrielStaples Sí, una excepción atrapada se puede volver a usar raise. Sin embargo, generalmente solo haría esto en algunas ubicaciones dentro de su aplicación para registrar la excepción.
meter el
Esto es genial, evite pasar excepto los bloques. Yo diría que haga lo que parezca más comprensible, especialmente para los demás. Obtenga un segundo conjunto de ojos de python para revisar su código y ver si cuestionan el bloqueo. La legibilidad es la clave.
Radtek
262

El principal problema aquí es que ignora todo y cualquier error: sin memoria, la CPU se está quemando, el usuario quiere parar, el programa quiere salir, Jabberwocky está matando a los usuarios.

Esto es demasiado. En tu cabeza, estás pensando "Quiero ignorar este error de red". Si algo inesperado sale mal, entonces su código continúa en silencio y se rompe de una manera completamente impredecible que nadie puede depurar.

Es por eso que debe limitarse a ignorar específicamente solo algunos errores y dejar pasar el resto.

Aaron Digulla
fuente
75

Ejecutar su pseudocódigo literalmente ni siquiera da ningún error:

try:
    something
except:
    pass

como si fuera un código perfectamente válido, en lugar de lanzar un NameError. Espero que esto no sea lo que quieres.

YS-L
fuente
51

¿Por qué "except: pass" es una mala práctica de programación?

¿Por qué es esto malo?

try:
    something
except:
    pass

Esto detecta todas las excepciones posibles, incluidas GeneratorExit, KeyboardInterrupty SystemExit, que son excepciones que probablemente no pretendes detectar. Es lo mismo que atrapar BaseException.

try:
    something
except BaseException:
    pass

Las versiones anteriores de la documentación dicen :

Dado que cada error en Python genera una excepción, el uso except:puede hacer que muchos errores de programación parezcan problemas de tiempo de ejecución, lo que dificulta el proceso de depuración.

Jerarquía de excepciones de Python

Si captura una clase de excepción principal, también captura todas sus clases secundarias. Es mucho más elegante capturar solo las excepciones que está preparado para manejar.

Aquí está la jerarquía de excepciones de Python 3 : ¿realmente quieres atraparlos a todos ?:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- StopIteration
      +-- StopAsyncIteration
      +-- ArithmeticError
      |    +-- FloatingPointError
      |    +-- OverflowError
      |    +-- ZeroDivisionError
      +-- AssertionError
      +-- AttributeError
      +-- BufferError
      +-- EOFError
      +-- ImportError
           +-- ModuleNotFoundError
      +-- LookupError
      |    +-- IndexError
      |    +-- KeyError
      +-- MemoryError
      +-- NameError
      |    +-- UnboundLocalError
      +-- OSError
      |    +-- BlockingIOError
      |    +-- ChildProcessError
      |    +-- ConnectionError
      |    |    +-- BrokenPipeError
      |    |    +-- ConnectionAbortedError
      |    |    +-- ConnectionRefusedError
      |    |    +-- ConnectionResetError
      |    +-- FileExistsError
      |    +-- FileNotFoundError
      |    +-- InterruptedError
      |    +-- IsADirectoryError
      |    +-- NotADirectoryError
      |    +-- PermissionError
      |    +-- ProcessLookupError
      |    +-- TimeoutError
      +-- ReferenceError
      +-- RuntimeError
      |    +-- NotImplementedError
      |    +-- RecursionError
      +-- SyntaxError
      |    +-- IndentationError
      |         +-- TabError
      +-- SystemError
      +-- TypeError
      +-- ValueError
      |    +-- UnicodeError
      |         +-- UnicodeDecodeError
      |         +-- UnicodeEncodeError
      |         +-- UnicodeTranslateError
      +-- Warning
           +-- DeprecationWarning
           +-- PendingDeprecationWarning
           +-- RuntimeWarning
           +-- SyntaxWarning
           +-- UserWarning
           +-- FutureWarning
           +-- ImportWarning
           +-- UnicodeWarning
           +-- BytesWarning
           +-- ResourceWarning

No hagas esto

Si está utilizando esta forma de manejo de excepciones:

try:
    something
except: # don't just do a bare except!
    pass

Entonces no podrás interrumpir tu somethingbloqueo con Ctrl-C. Su programa pasará por alto todas las excepciones posibles dentro deltry bloque de código.

Aquí hay otro ejemplo que tendrá el mismo comportamiento indeseable:

except BaseException as e: # don't do this either - same as bare!
    logging.info(e)

En su lugar, intente detectar solo la excepción específica que sabe que está buscando. Por ejemplo, si sabe que puede obtener un error de valor en una conversión:

try:
    foo = operation_that_includes_int(foo)
except ValueError as e:
    if fatal_condition(): # You can raise the exception if it's bad,
        logging.info(e)   # but if it's fatal every time,
        raise             # you probably should just not catch it.
    else:                 # Only catch exceptions you are prepared to handle.
        foo = 0           # Here we simply assign foo to 0 and continue. 

Explicación adicional con otro ejemplo

Puede que lo estés haciendo porque has estado raspando la web y te han estado diciendo, un UnicodeError pero debido a que ha utilizado la captura de excepciones más amplia, su código, que puede tener otros defectos fundamentales, intentará ejecutarse hasta su finalización, desperdiciando ancho de banda , tiempo de procesamiento, desgaste de su equipo, falta de memoria, recopilación de datos basura, etc.

Si otras personas le piden que complete para que puedan confiar en su código, entiendo que me siento obligado a manejar todo. Pero si está dispuesto a fallar ruidosamente a medida que se desarrolla, tendrá la oportunidad de corregir problemas que pueden aparecer de manera intermitente, pero que serían errores costosos a largo plazo.

Con un manejo de errores más preciso, su código puede ser más robusto.

Aaron Hall
fuente
31
>>> import this

El zen de Python, por Tim Peters

Hermoso es mejor que feo.
Explícito es mejor que implícito.
Lo simple es mejor que lo complejo.
Complejo es mejor que complicado.
Plano es mejor que anidado.
Escaso es mejor que denso.
La legibilidad cuenta.
Los casos especiales no son lo suficientemente especiales como para romper las reglas.
Aunque la practicidad supera la pureza.
Los errores nunca deben pasar en silencio.
A menos que sea silenciado explícitamente.
Ante la ambigüedad, rechaza la tentación de adivinar.
Debe haber una, y preferiblemente solo una, forma obvia de hacerlo.
Aunque esa manera puede no ser obvia al principio a menos que seas holandés.
Ahora es mejor que nunca.
Aunque nunca es mejor quederecho ahora.
Si la implementación es difícil de explicar, es una mala idea.
Si la implementación es fácil de explicar, puede ser una buena idea.
Los espacios de nombres son una gran idea, ¡hagamos más de eso!

Entonces, aquí está mi opinión. Siempre que encuentre un error, debe hacer algo para manejarlo, es decir, escribirlo en el archivo de registro u otra cosa. Al menos, le informa que solía haber un error.

Aumentador de presión
fuente
64
-1 El argumento de la autoridad en realidad no explica nada. La autoridad puede estar equivocada.
Izkata
23
lo que escribió @Izkata, Y, una línea debajo de él, la misma autoridad escribe: "A menos que se silencie explícitamente", que es exactamente lo que excepto: pasa.
Ofri Raviv
13
@OfriRaviv No, ¿el error no pasa implícitamente ? Explícitamente requeriría nombrar el error que debería pasar en silencio, es decir, ser explícito al respecto . Esto no es lo que excepto: pase hace.
Chelonian
24

Debe usar al menos except Exception:para evitar la captura de excepciones del sistema como SystemExito KeyboardInterrupt. Aquí hay un enlace a los documentos.

En general, debe definir explícitamente las excepciones que desea capturar, para evitar la captura de excepciones no deseadas. Debe saber qué excepciones ignora .

Tupteq
fuente
13

Primero, viola dos principios del Zen de Python :

  • Explícito es mejor que implícito
  • Los errores nunca deben pasar en silencio

Lo que significa es que intencionalmente hace que su error pase en silencio. Además, no sabe qué evento ocurrió exactamente, porque except: passdetectará cualquier excepción.

En segundo lugar, si tratamos de abstraernos del Zen de Python y hablar en términos de cordura justa, debes saber que usarlo except:passte deja sin conocimiento y control en tu sistema. La regla general es generar una excepción, si ocurre un error, y tomar las medidas apropiadas. Si no sabe de antemano, qué acciones deberían ser, al menos registre el error en alguna parte (y mejor vuelva a plantear la excepción):

try:
    something
except:
    logger.exception('Something happened')

Pero, por lo general, si intenta detectar alguna excepción, ¡probablemente esté haciendo algo mal!

Alexander Zhukov
fuente
2
... A menos que esté silenciado explícitamente, que es el caso con OP.
Hyperboreus
Quiero saber tu solución. De hecho, cuando realmente no hay nada que hacer, solo enumero los errores excepto y hago comentarios y escribo registros. Entonces solo pasa.
Booster
2
@Hyperboreus, no creo, que atrapar todos y cualquier error los esté silenciando explícitamente, es decir, ni siquiera sabe qué atrapa.
Alexander Zhukov
13
"Porque un tipo lo dice" no es realmente una respuesta a un "¿Por qué?" pregunta.
Sebastian Negraszus
12

La except:passconstrucción esencialmente silencia todas y cada una de las condiciones excepcionales que surgen mientras try:se ejecuta el código cubierto en el bloque.

Lo que hace que esta mala práctica sea que generalmente no es lo que realmente quieres. Más a menudo, surge una condición específica que desea silenciar, y except:passes demasiado un instrumento contundente. Hará el trabajo, pero también enmascarará otras condiciones de error que probablemente no haya anticipado, pero que muy bien quiera tratar de alguna otra manera.

Lo que hace que esto sea particularmente importante en Python es que, por las expresiones idiomáticas de este lenguaje, las excepciones no son necesariamente errores . A menudo se usan de esta manera, por supuesto, al igual que en la mayoría de los idiomas. Pero Python en particular los ha usado ocasionalmente para implementar una ruta de salida alternativa de algunas tareas de código que no es realmente parte del caso de ejecución normal, pero aún se sabe que aparece de vez en cuando e incluso se puede esperar en la mayoría de los casos. SystemExitya se ha mencionado como un viejo ejemplo, pero el ejemplo más común hoy en día puede ser StopIteration. El uso de excepciones de esta manera causó mucha controversia, especialmente cuando los iteradores y generadores se presentaron por primera vez a Python, pero finalmente prevaleció la idea.

El más cuchara
fuente
12

La razón # 1 ya se ha indicado: oculta errores que no esperaba.

(# 2) - Hace que su código sea difícil de leer y entender para otros. Si detecta una excepción FileNotFoundException cuando intenta leer un archivo, entonces es bastante obvio para otro desarrollador qué funcionalidad debería tener el bloque 'catch'. Si no especifica una excepción, necesita comentarios adicionales para explicar qué debe hacer el bloque.

(# 3) - Demuestra una programación perezosa. Si usa el try / catch genérico, indica que no comprende los posibles errores de tiempo de ejecución en su programa o que no sabe qué excepciones son posibles en Python. Detectar un error específico muestra que comprende tanto su programa como el rango de errores que arroja Python. Es más probable que esto haga que otros desarrolladores y revisores de código confíen en su trabajo.

Kevin
fuente
12

Entonces, ¿qué salida produce este código?

fruits = [ 'apple', 'pear', 'carrot', 'banana' ]

found = False
try:
     for i in range(len(fruit)):
         if fruits[i] == 'apple':
             found = true
except:
     pass

if found:
    print "Found an apple"
else:
    print "No apples in list"

Ahora imagine que el bloque try- exceptes cientos de líneas de llamadas a una jerarquía de objetos complejos, y se llama a sí mismo en medio del árbol de llamadas del programa grande. Cuando el programa sale mal, ¿dónde comienzas a buscar?

Ian Harvey
fuente
55
Er, gracias a la gente que 'corrigió' esto, pero no lo hagas, es intencionalmente incorrecto, en el sentido de 'pregunta de entrevista'. Posiblemente sea más sutil de lo que parece, pruébalo. Mi punto es que aplastar 'todas' las excepciones, especialmente en Python, dificulta la depuración, incluso en una docena de líneas de código triviales.
Ian Harvey
11

En general, puede clasificar cualquier error / excepción en una de tres categorías :

  • Fatal : No es tu culpa, no puedes evitarlos, no puedes recuperarte de ellos. Ciertamente no debe ignorarlos y continuar, y dejar su programa en un estado desconocido. Simplemente deje que el error termine su programa, no hay nada que pueda hacer.

  • Deshonesto : su propia culpa, muy probablemente debido a un descuido, error o error de programación. Deberías arreglar el error. Una vez más, sin duda no debe ignorar y continuar.

  • Exógeno : puede esperar estos errores en situaciones excepcionales, como archivos no encontrados o conexión terminada . Debe manejar explícitamente estos errores, y solo estos.

En todos los casos except: passsolo dejará su programa en un estado desconocido, donde puede causar más daño.

Daniel AA Pelsmaeker
fuente
6

En pocas palabras, si se produce una excepción o error, algo está mal. Puede que no sea algo muy malo, pero crear, arrojar y capturar errores y excepciones solo por el uso de declaraciones goto no es una buena idea, y rara vez se hace. El 99% del tiempo, hubo un problema en alguna parte.

Los problemas deben ser resueltos. Al igual que en la vida, en la programación, si dejas los problemas en paz y tratas de ignorarlos, no desaparecen solos muchas veces; en cambio se hacen más grandes y se multiplican. Para evitar que un problema crezca en usted y golpee nuevamente más adelante en el camino, 1) lo elimina y limpia el desorden después, o 2) lo contiene y limpia el desorden después.

Simplemente ignorar excepciones y errores y dejarlos así es una buena manera de experimentar pérdidas de memoria, conexiones de bases de datos sobresalientes, bloqueos innecesarios en los permisos de archivos, etc.

En raras ocasiones, el problema es tan minúsculo, trivial y, aparte de necesitar un intento ... de captura, autocontenido , que realmente no hay ningún desastre que limpiar después. Estas son las únicas ocasiones en que esta mejor práctica no se aplica necesariamente. En mi experiencia, esto generalmente ha significado que lo que sea que esté haciendo el código es básicamente insignificante y olvidable, y algo como intentos de reintento o mensajes especiales no valen ni la complejidad ni el mantener el hilo.

En mi compañía, la regla es casi siempre hacer algo en un bloque de captura, y si no haces nada, siempre debes colocar un comentario con una muy buena razón por la que no. Nunca debe pasar o dejar un bloque de captura vacío cuando hay algo que hacer.

Panzercrisis
fuente
6

En mi opinión, los errores tienen una razón para aparecer, que mi sonido suena estúpido, pero así son las cosas. Una buena programación solo genera errores cuando hay que manejarlos. Además, como leí hace algún tiempo, "la declaración de aprobación es una declaración que muestra que el código se insertará más tarde", por lo que si desea tener una declaración de excepción vacía, no dude en hacerlo, pero para un buen programa habrá ser una parte que falta porque no manejas las cosas que deberías tener. Las excepciones que aparecen le dan la oportunidad de corregir los datos de entrada o de cambiar su estructura de datos para que estas excepciones no ocurran nuevamente (pero en la mayoría de los casos (excepciones de red, excepciones de entrada generales) las excepciones indican que las siguientes partes del programa no se ejecutarán bien. Por ejemplo, una excepción de red puede indicar una conexión de red interrumpida y el programa no puede enviar / recibir datos en los siguientes pasos del programa.

Pero usar un bloque de paso para un solo bloque de ejecución es válido, ya que todavía diferencia entre los tipos de excepciones, por lo que si coloca todos los bloques de excepción en uno, no está vacío:

try:
    #code here
except Error1:
    #exception handle1

except Error2:
    #exception handle2
#and so on

puede reescribirse de esa manera:

try:
    #code here
except BaseException as e:
    if isinstance(e, Error1):
        #exception handle1

    elif isinstance(e, Error2):
        #exception handle2

    ...

    else:
        raise

Por lo tanto, incluso varios bloques de excepción con sentencias de paso pueden generar código, cuya estructura maneja tipos especiales de excepciones.

Sirac
fuente
4

Todos los comentarios mencionados hasta ahora son válidos. Siempre que sea posible, debe especificar qué excepción exacta desea ignorar. Siempre que sea posible, debe analizar qué causó la excepción y solo ignorar lo que quiso ignorar, y no el resto. Si la excepción hace que la aplicación se "bloquee espectacularmente", entonces sea así, porque es mucho más importante saber lo inesperado que sucedió cuando sucedió, que ocultar que el problema alguna vez ocurrió.

Con todo lo dicho, no tome ninguna práctica de programación como primordial. Esto es estupido Siempre existe el momento y el lugar para hacer el bloque ignorar todas las excepciones.

Otro ejemplo de lo más idiota es el uso del gotooperador. Cuando estaba en la escuela, nuestro profesor nos enseñó el gotooperador solo para mencionar que nunca lo usarás. No le creas a las personas que te dicen que xyz nunca debe usarse y que no puede haber un escenario cuando sea útil. Siempre hay.

galets
fuente
1
El caso "goto" es estilístico y es una cuestión de opinión, mientras que "excepto: pasar" suele ser erróneo. Se supone que si alguien fuera, por ejemplo, a "matar -TERM" su proceso en ese punto, entonces debería ignorarlo. Por lo menos eso es mal comportamiento.
Score_Under
1
@Score_Under todavía hay casos en que esto es apropiado para usar. Por ejemplo, cuando una función que está llamando es complementaria, de origen / autor desconocido, no afecta la funcionalidad principal, pero si los bloqueos pueden causar problemas. Me doy cuenta de que argumentaría que tales llamadas deberían investigarse y analizarse adecuadamente, pero en la vida real no siempre es posible.
galets
Aún así, si quiero terminar su proceso, kill -9 no debería ser la única opción confiable.
Score_Under
2

El manejo de errores es muy importante en la programación. Es necesario mostrarle al usuario lo que salió mal. En muy pocos casos puede ignorar los errores. Esta es una muy mala práctica de programación.

fastcodejava
fuente
2

Como aún no se ha mencionado, es mejor usar el estilo contextlib.suppress:

with suppress(FileNotFoundError):
    os.remove('somefile.tmp')

Tenga en cuenta que en el ejemplo proporcionado, el estado del programa sigue siendo el mismo, se produzca o no la excepción. Es decir, somefile.tmpsiempre se vuelve inexistente.

Mateen Ulhaq
fuente