Sobes.tech
Middle

¿Cómo funcionan las excepciones anidadas en Python?

sobes.tech AI

Respuesta de la IA

Las excepciones anidadas, también conocidas como encadenamiento de excepciones, permiten mantener información sobre la excepción previa cuando surge una nueva. Esto es útil para la depuración y comprensión de las causas del error.

En Python 3, por defecto, cuando se produce una nueva excepción dentro de un bloque except o finally, la excepción original se vincula automáticamente con la nueva.

Esta vinculación se almacena en el atributo __cause__ de la nueva excepción.

La vinculación explícita puede realizarse usando la palabra clave raise from.

# Ejemplo de vinculación automática
def divide(a, b):
    try:
        return a / b
    except TypeError:
        # Durante el manejo de TypeError puede surgir otra excepción
        # La excepción original (TypeError) estará vinculada a la nueva
        raise ValueError("Tipo de operandos incorrecto")

try:
    divide("a", 0)
except ValueError as e:
    # e.__cause__ contendrá un TypeError
    print(f"Error ocurrido: {e}")
    if e.__cause__:
        print(f"Causado por: {e.__cause__}")

print("-" * 20)

# Ejemplo de vinculación explícita con raise from
class CustomError(Exception):
    pass

def tricky_function():
    try:
        # Intento de división por cero, genera ZeroDivisionError
        result = 1 / 0
    except ZeroDivisionError as original_exc:
        # Crear una nueva excepción y vincularla con la original
        raise CustomError("Error en el cálculo") from original_exc

try:
    tricky_function()
except CustomError as e:
    # e.__cause__ contendrá ZeroDivisionError
    print(f"Error ocurrido: {e}")
    if e.__cause__:
        print(f"Causado por: {e.__cause__}")

print("-" * 20)

# Supresión de la vinculación con raise ... from None
try:
    try:
        # Excepción original
        raise ValueError("Error original")
    except ValueError:
        # Durante el manejo de ValueError surge otra excepción,
        # pero la vinculación se suprime
        raise TypeError("Nueva error") from None
except TypeError as e:
    # e.__cause__ será None
    print(f"Error ocurrido: {e}")
    if e.__cause__ is None:
        print("Razón no especificada.")

La palabra clave raise sin argumentos vuelve a lanzar la última excepción.

# Ejemplo de re-lanzamiento de excepción
def process_data(data):
    try:
        # Supongamos que aquí algo puede fallar
        if not data:
            raise ValueError("Faltan datos")
        print("Datos procesados")
    except ValueError:
        print("Capturado ValueError")
        # Re-lanzar la misma excepción
        raise

try:
    process_data("")
except ValueError as e:
    print(f"Excepción re-lanzada capturada: {e}")

Las excepciones anidadas mejoran la legibilidad de las trazas de errores y ayudan a localizar más rápidamente la causa raíz del problema.