CodeGym /Cursos /Python SELF ES /Creación de tu propia excepción

Creación de tu propia excepción

Python SELF ES
Nivel 18 , Lección 1
Disponible

7.1 Creación de excepciones personalizadas

A veces las excepciones estándar de Python no satisfacen completamente las necesidades de tu aplicación. En tales casos, puedes crear tus propias excepciones heredándolas de la clase base Exception o de cualquier otra clase de excepciones adecuada.

Fundamentos de la creación de excepciones personalizadas

Crear una excepción personalizada implica definir una nueva clase que se hereda de la clase base Exception. Puedes añadir tus propios métodos y atributos a tu clase de excepción para proporcionar información adicional sobre el error.

Ejemplo de creación de una excepción personalizada simple

Paso 1: Definición de la excepción personalizada


class MyCustomError(Exception):
    """Clase para la excepción personalizada."""
    pass

Paso 2: Uso de la excepción personalizada


def check_value(value):
    if value < 0:
        raise MyCustomError("El valor no debe ser menor que cero")
            
try:
    check_value(-1)
except MyCustomError as e:
    print(f"Ocurrió una excepción personalizada: {e}")

Todo es muy sencillo. Lo principal es que tu excepción debe heredarse de la clase Exception o de uno de sus descendientes.

7.2 Creación de excepciones con atributos adicionales

Puedes añadir atributos y métodos a tu clase de excepción para pasar información adicional sobre el error que ocurrió.

Ejemplo:


class NegativeValueError(Exception):
    """Clase para la excepción personalizada en caso de valor negativo."""
    def __init__(self, value, message = "El valor no debe ser menor que cero"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

Uso de excepción con atributos adicionales


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)

try:
    check_value(-1)
except NegativeValueError as e:
    print(f"Ocurrió una excepción personalizada: {e}")

Nuestra excepción es una clase que hereda de la clase Exception. Por lo tanto, puedes hacer todo lo que harías con cualquier otra clase: agregar campos, métodos, parámetros de constructor, etc.

Todo para tu comodidad, y la comodidad de los programadores que interceptarán tus excepciones.

7.3 Creación de jerarquía de excepciones personalizadas

Para aplicaciones más complejas, es útil crear jerarquías de excepciones personalizadas. Esto permite agrupar excepciones relacionadas y simplificar su manejo.

Ejemplo:


class ApplicationError(Exception):
    """Clase base para todas las excepciones de la aplicación."""
    pass

class NegativeValueError(ApplicationError):
    """Clase para la excepción personalizada en caso de valor negativo."""
    def __init__(self, value, message="El valor no debe ser menor que cero"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

class ValueTooLargeError(ApplicationError):
    """Clase para la excepción personalizada en caso de valor demasiado grande."""
    def __init__(self, value, message="El valor es demasiado grande"):
        self.value = value
        self.message = message
        super().__init__(self.message)

    def __str__(self):
        return f'{self.message}: {self.value}'

Uso de jerarquía de excepciones personalizadas


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)

try:
    check_value(150)
except NegativeValueError as e:
    print(f"Ocurrió una excepción: {e}")
except ValueTooLargeError as e:
    print(f"Ocurrió una excepción: {e}")
except ApplicationError as e:
    print(f"Excepción general de la aplicación: {e}")

7.4 Orden de captura de excepciones

Al capturar excepciones, especialmente de una misma jerarquía, es importante especificar su orden correcto. Y aunque el código dentro de los bloques except nunca se ejecuta simultáneamente, la cuestión es que la clase base de excepciones puede capturar excepciones de todas las clases derivadas.

Por ejemplo, el código:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
    
try:
    check_value(150)
except ApplicationError as e: # capturará excepciones del tipo ApplicationError y todos sus descendientes
    print(f"Excepción general de la aplicación: {e}")

En el bloque except se capturarán excepciones del tipo ApplicationError y todos sus clases derivadas.

Y dado que todas las excepciones son descendientes de la clase Exception, tal código capturará todas las excepciones:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
    
try:
    check_value(150)
except Exception as e:
    print(f"Captura de todas las excepciones: {e}")
except ApplicationError as e: # Este código nunca se ejecutará
    print(f"Excepción general de la aplicación: {e}")

La captura de excepciones en el bloque except ApplicationError nunca ocurrirá, ya que el bloque except Exception capturará todas las excepciones del tipo Exception y cualquiera de sus descendientes.

Solución

Por lo tanto, es costumbre capturar excepciones en el orden inverso al de la herencia: cuanto más cerca esté la clase de la clase Exception, más abajo se encuentra.

Ejemplo:


def check_value(value):
    if value < 0:
        raise NegativeValueError(value)
    elif value > 100:
        raise ValueTooLargeError(value)
        
try:
    check_value(150)
except NegativeValueError as e:
    print(f"Ocurrió una excepción: {e}")
except ApplicationError as e:
    print(f"Excepción general de la aplicación: {e}")
except Exception as e:
    print(f"Captura de todas las excepciones: {e}")

En este ejemplo, los bloques except están dispuestos en el orden que corresponde a su jerarquía de herencia: primero se capturan las excepciones más específicas, como NegativeValueError, luego las más generales, como ApplicationError. Esto permite manejar correctamente las excepciones y evitar situaciones en las que un manejador más general capture una excepción antes de que puedan manejarla bloques except más especializados.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION