ProgramaciónDesarrollador Backend

Describe los mecanismos de manejo de excepciones en Python. ¿Cómo funciona el bloque try/except/finally, para qué se utiliza raise y cuáles son las trampas comunes?

Supere entrevistas con el asistente de IA Hintsage

Respuesta

En Python, el manejo de excepciones se implementa a través de las construcciones try/except/else/finally y la sentencia raise.

try define un bloque de código protegido. Si ocurre una excepción dentro, el control se transfiere al bloque except más cercano que sea apropiado. Si no hay excepciones, se ejecuta el bloque else, si existe. El bloque finally se ejecuta siempre, independientemente de si hubo o no una excepción (por ejemplo, para liberar recursos).

La sentencia raise provoca explícitamente una excepción o vuelve a lanzar la actual (en el bloque except sin especificar el tipo).

Ejemplo:

try: x = 1 / 0 except ZeroDivisionError as e: print(f"Error: {e}") else: print("No hubo errores") finally: print("Siempre se ejecuta")

Salida:

Error: division by zero
Siempre se ejecuta

Detalles:

  • En los manejadores anidados, es importante el orden de except: de tipos específicos a más generales (de lo contrario, los específicos no serán manejados).
  • El bloque finally no puede prevenir un nuevo lanzamiento de la excepción (si pones raise dentro de finally, se aplica el error "más reciente").

Pregunta capciosa

Pregunta: "¿Qué pasará si en el bloque try y en finally se lanza raise con diferentes excepciones?"

Respuesta: La excepción de finally "cubrirá" la excepción de try: saldrá aquello que emergió en finally.

def foo(): try: raise ValueError("en try") finally: raise IndexError("en finally") try: foo() except Exception as e: print(repr(e)) # Salida: IndexError('en finally')

Ejemplos de errores reales debido al desconocimiento de los detalles del tema


Historia

En un proceso ETL, la conexión a la base de datos se cerraba incondicionalmente en el bloque finally, pero se olvidaban de que en finally podría ocurrir una excepción (por ejemplo, si la conexión ya estaba cerrada). El resultado — una excepción "oculta" de finally absorbía completamente la excepción del código principal, complicando drásticamente la depuración.


Historia

Se usaron cadenas de varios except: comenzando desde un except Exception general sobre los específicos. Como resultado, todos los except específicos permanecían "muertos" — las excepciones de bajo nivel no se atrapaban por separado, lo que dificultaba el manejo de errores específicos.


Historia

En un servicio web, se olvidaban de propagar la excepción en el except mediante "raise", registrando el error, pero permitiendo que la ejecución continuara. Como resultado, los errores reales se "perdían", y el programa continuaba funcionando en un estado incorrecto.