¿Debo especificar siempre un tipo de excepción en las declaraciones `except`?

Cuando se utiliza el IDE de PyCharm, el uso de except: sin un tipo de excepción desencadena un recordatorio del IDE de que esta cláusula de excepción es Too broad .

¿Debo estar ignorando este consejo? ¿O es Pythonic para especificar siempre el tipo de excepción?

Casi siempre es mejor especificar un tipo de excepción explícito. Si usa una cláusula de except: desnuda, podría terminar atrapando excepciones distintas de las que espera detectar, esto puede ocultar errores o hacer más difícil la depuración de progtwigs cuando no están haciendo lo que usted espera.

Por ejemplo, si está insertando una fila en una base de datos, es posible que desee detectar una excepción que indique que la fila ya existe, por lo que puede hacer una actualización.

 try: insert(connection, data) except: update(connection, data) 

Si especifica un simple except: también detectaría un error de socket que indica que el servidor de la base de datos se ha caído. Es mejor detectar solo las excepciones que sabe manejar; a menudo es mejor que el progtwig falle en el punto de la excepción que continuar, pero comportarse de formas extrañas e inesperadas.

Un caso en el que podría querer usar un simple except: es en el nivel superior de un progtwig que siempre debe estar ejecutando, como un servidor de red. Pero entonces, debe tener mucho cuidado de registrar las excepciones, de lo contrario será imposible averiguar qué está mal. Básicamente, solo debe haber como máximo un lugar en un progtwig que haga esto.

Un corolario de todo esto es que su código nunca debe raise Exception('some message') porque obliga al código del cliente a usar except: (o except Exception: que es casi tan malo). Debe definir una excepción específica para el problema que desea señalar (tal vez heredar de alguna subclase de excepción ValueError como ValueError o TypeError ). O debería plantear una excepción incorporada específica. Esto permite a los usuarios de su código tener cuidado al capturar solo las excepciones que desean manejar.

No debe ignorar los consejos que le da el intérprete.

De la guía de estilo PEP-8 para Python:

Cuando detecte excepciones, mencione las excepciones específicas siempre que sea posible en lugar de usar una cláusula bare except:.

Por ejemplo, use:

  try: import platform_specific_module except ImportError: platform_specific_module = None 

Una simple excepción: la cláusula detectará las excepciones de SystemExit y KeyboardInterrupt, lo que dificultará la interrupción de un progtwig con Control-C y puede disimular otros problemas. Si desea detectar todas las excepciones que señalan errores de progtwig, utilice excepto Excepción: (solo excepto es equivalente a excepto BaseException :).

Una buena regla general es limitar el uso de cláusulas ‘excepto’ en dos casos:

Si el controlador de excepciones imprimirá o registrará el rastreo; al menos el usuario será consciente de que ha ocurrido un error. Si el código necesita hacer algún trabajo de limpieza, pero luego deja que la excepción se propague hacia arriba con el aumento. intentar … finalmente puede ser una mejor manera de manejar este caso.

No es específico para Python esto.

El punto principal de las excepciones es tratar el problema lo más cerca posible del problema.

De modo que conserva el código que, en circunstancias excepcionales, podría desencadenar el problema y la resolución “siguiente” entre sí.

La cosa es que no puedes saber todas las excepciones que podrían ser lanzadas por un pedazo de código. Todo lo que puede saber es que si se trata de una excepción, por ejemplo, un archivo no encontrado, podría interceptarlo y pedirle al usuario que obtenga uno que lo haga o cancele la función.

Si lo intenta, no importa qué problema haya en su rutina de archivos (solo lectura, permisos, UAC, en realidad no es un pdf, etc.), todos ingresarán a su archivo no encontrado, y su usuario está gritando “pero está ahí, este código es una mierda”

Ahora hay un par de situaciones en las que puedes atrapar todo, pero deben elegirse conscientemente.

Son capturas, deshacer alguna acción local (como crear o bloquear un recurso, (abrir un archivo en el disco para escribir, por ejemplo), luego lanzar la excepción otra vez, para que sea tratada a un nivel superior)

El otro tú es que no te importa por qué salió mal. Impresión por ejemplo. Es posible que tenga un problema general alrededor de eso, por ejemplo. Hay algún problema con su impresora, resuélvalo y no elimine la aplicación por eso. En un caso similar, si su código ejecutó una serie de tareas separadas utilizando algún tipo de progtwigción, no querría que todo muriera, porque una de las tareas falló.

Nota Si hace lo anterior, no puedo recomendar algún tipo de registro de excepciones, por ejemplo, intente capturar el final del registro, lo suficiente.

También atraparás, por ejemplo, Control-C, así que no lo hagas a menos que lo “lances” de nuevo. Sin embargo, en ese caso deberías usar “finalmente”.

Siempre especifique el tipo de excepción, hay muchos tipos que no desea capturar, como SyntaxError , KeyboardInterrupt , MemoryError , etc.

Aquí están los lugares donde uso excepto sin tipo

  1. Prototipado rápido y sucio.

Ese es el uso principal en mi código para excepciones no verificadas

  1. función principal () de nivel superior, donde registro todas las excepciones no detectadas

Siempre agrego esto, para que el código de producción no derrame stacktraces

  1. entre capas de aplicación

Tengo dos formas de hacerlo:

  • Primera forma de hacerlo: cuando una capa de nivel superior llama a una función de nivel inferior, envuelve las llamadas con excepciones escritas para manejar las excepciones de nivel inferior “superiores”. Pero agrego una statement de excepción genérica, para detectar excepciones de nivel inferior no manejadas en las funciones de nivel inferior.

Lo prefiero de esta manera, me resulta más fácil detectar qué excepciones deberían haberse capturado adecuadamente: “veo” mejor el problema cuando se registra una excepción de nivel inferior por un nivel superior

  • Segunda forma de hacerlo: cada función de nivel superior de las capas de nivel inferior tiene su código envuelto en un genérico, excepto que captura todas las excepciones no manejadas en esa capa específica.

Algunos compañeros de trabajo prefieren esta forma, ya que mantiene las excepciones de nivel inferior en las funciones de nivel inferior, donde “pertenecen”.

Prueba esto:

 try: #code except ValueError: pass 

Obtuve la respuesta de este enlace, si alguien más se encuentra con este problema , compruébalo