35- Try Except en Python

Acordeón de los Índices




🛡️ Python Try Except

En Python, las declaraciones try y except se utilizan para manejar errores que pueden ocurrir durante la ejecución de un programa. Este proceso se conoce como manejo de excepciones.

Cuando ocurre un error en Python, se levanta una excepción. Si esta excepción no se maneja, el programa se detiene abruptamente. El bloque try te permite probar un bloque de código en busca de errores, y el bloque except te permite definir qué hacer si ocurre un error.

Sintaxis básica:

                    try:
    # Bloque de código que podría generar un error
    # ...
except TipoDeError:
    # Bloque de código que se ejecuta si ocurre un error del tipo especificado
    # ...
                    
                

Ejemplo: División por cero

Un error común es la división por cero, que en Python levanta una excepción del tipo ZeroDivisionError. Podemos manejar esta excepción de la siguiente manera:

                    try:
    resultado = 10 / 0
    print(f"El resultado es: {resultado}")
except ZeroDivisionError:
    print("¡Error! No se puede dividir por cero.")
                    
                

En este ejemplo, la línea resultado = 10 / 0 generaría un ZeroDivisionError. Sin embargo, como está dentro de un bloque try y hemos definido un bloque except ZeroDivisionError, en lugar de detenerse el programa, se ejecutará el código dentro del except, mostrando el mensaje de error.

El uso de try y except es fundamental para escribir programas robustos que puedan recuperarse de errores inesperados y continuar su ejecución de manera controlada.

🛡️ Exception Handling

El manejo de excepciones es un mecanismo poderoso en Python que permite a los programas responder de manera controlada a errores en tiempo de ejecución. En lugar de que el programa falle, puedes anticipar posibles problemas y definir cómo quieres que el programa se comporte si ocurren.

¿Por qué es importante el manejo de excepciones?

  • Robustez: Hace que tus programas sean más resistentes a fallos inesperados.
  • Experiencia del usuario: Permite proporcionar mensajes de error amigables en lugar de rastreos técnicos confusos.
  • Continuidad: Permite que el programa intente recuperarse del error o, al menos, finalizar de manera limpia.

Manejo de excepciones específicas:

En el ejemplo anterior, manejamos específicamente la excepción ZeroDivisionError. Es una buena práctica ser lo más específico posible sobre el tipo de excepción que esperas manejar. Python tiene una jerarquía de excepciones incorporadas, y puedes capturar tipos específicos o clases base de excepciones.

Ejemplo: Manejando `TypeError`

                    try:
    resultado = "5" + 5
    print(f"El resultado es: {resultado}")
except TypeError:
    print("¡Error! Operación no válida entre tipos.")
                    
                

Aquí, intentamos sumar una cadena y un entero, lo que genera un TypeError. El bloque except TypeError captura este error y muestra un mensaje apropiado.

Capturando múltiples tipos de excepciones:

Puedes manejar múltiples tipos de excepciones en bloques except separados:

                    try:
    valor = int(input("Introduce un número: "))
    resultado = 10 / valor
    print(f"El resultado es: {resultado}")
except ValueError:
    print("¡Error! Debes introducir un número entero.")
except ZeroDivisionError:
    print("¡Error! No se puede dividir por cero.")
                    
                

En este caso, si el usuario introduce algo que no es un entero, se levantará un ValueError. Si introduce cero, se levantará un ZeroDivisionError, y cada excepción se maneja con su propio mensaje.

El manejo adecuado de las excepciones es una habilidad clave en la programación en Python que conduce a la creación de software más confiable y fácil de usar.

➕ Many Exceptions

En el tema anterior, vimos cómo manejar diferentes tipos de excepciones utilizando múltiples bloques except. Python también te permite manejar múltiples excepciones en un solo bloque except utilizando una tupla de los tipos de excepción.

Sintaxis para manejar múltiples excepciones en un bloque:

                    try:
    # Bloque de código que podría generar varios tipos de errores
    # ...
except (TipoDeError1, TipoDeError2, ...):
    # Bloque de código que se ejecuta si ocurre cualquiera de los errores especificados
    # ...
                    
                

Esto es útil cuando quieres ejecutar el mismo bloque de código de manejo para diferentes tipos de errores.

Ejemplo: Manejando `TypeError` y `ValueError` juntos

                    try:
    valor = input("Introduce un número: ")
    resultado = 10 + int(valor)  # Podría generar TypeError o ValueError
    print(f"El resultado es: {resultado}")
except (TypeError, ValueError):
    print("¡Error! Entrada inválida. Debes introducir un número.")
                    
                

En este ejemplo, si el usuario introduce una cadena que no se puede convertir a un entero, se generará un ValueError. Si por alguna razón la operación de suma con `10` falla debido al tipo de `valor` (aunque `int(valor)` debería prevenirlo si la conversión falla), se podría generar un TypeError. Ambos errores se manejan con el mismo mensaje.

Capturando la excepción como un objeto:

También puedes capturar la instancia de la excepción para acceder a información detallada sobre el error utilizando la sintaxis except TipoDeError as nombre_del_objeto:

                    try:
    resultado = 10 / 0
except ZeroDivisionError as e:
    print(f"¡Ocurrió un error de división por cero: {e}")
                    
                

Aquí, la excepción ZeroDivisionError se captura como el objeto `e`, y podemos imprimir una descripción del error proporcionada por la excepción.

Manejar múltiples excepciones de manera eficiente hace que tu código sea más limpio y fácil de mantener, especialmente cuando la respuesta a diferentes tipos de errores es la misma.

➡️ Else

Python te permite añadir un bloque else opcional después de todos los bloques except. El bloque else se ejecuta solo si el bloque try no levanta ninguna excepción.

Sintaxis del bloque `else`:

                    try:
    # Bloque de código que podría generar un error
    # ...
except TipoDeError:
    # Bloque de código que se ejecuta si ocurre un error del tipo especificado
    # ...
else:
    # Bloque de código que se ejecuta si NO ocurre ningún error en el bloque try
    # ...
                    
                

El bloque else es un buen lugar para colocar código que depende de que el bloque try se haya ejecutado con éxito. Esto ayuda a separar el manejo de errores del flujo principal del código cuando no hay errores.

Ejemplo: Usando `else` con división

                    try:
    numerador = int(input("Introduce el numerador: "))
    denominador = int(input("Introduce el denominador: "))
    resultado = numerador / denominador
except ValueError:
    print("¡Error! Debes introducir números enteros.")
except ZeroDivisionError:
    print("¡Error! No se puede dividir por cero.")
else:
    print(f"El resultado de la división es: {resultado}")
                    
                

En este ejemplo, si el usuario introduce dos enteros válidos y no se produce una división por cero, el bloque else se ejecutará e imprimirá el resultado de la división. Si ocurre alguna de las excepciones (`ValueError` o `ZeroDivisionError`), el bloque else se omitirá.

El bloque else proporciona una forma clara de especificar el código que debe ejecutarse en el caso de que la parte "try" de la declaración tenga éxito, lo que mejora la legibilidad y la estructura del código de manejo de excepciones.

⏱️ Finally

Python te permite incluir un bloque finally opcional después de los bloques except (y el bloque else, si está presente). El bloque finally siempre se ejecuta, independientemente de si ocurrió o no una excepción en el bloque try y de si se manejó o no.

Sintaxis del bloque `finally`:

                    try:
    # Bloque de código que podría generar un error
    # ...
except TipoDeError:
    # Bloque de código que se ejecuta si ocurre un error del tipo especificado
    # ...
else:
    # Bloque de código que se ejecuta si NO ocurre ningún error en el bloque try
    # ...
finally:
    # Bloque de código que SIEMPRE se ejecuta al final
    # ...
                    
                

El bloque finally se utiliza típicamente para realizar acciones de limpieza que deben ocurrir sin importar lo que pase en el bloque try, como cerrar archivos o liberar recursos.

Ejemplo: Usando `finally` para cerrar un archivo

                    archivo = None
try:
    archivo = open("mi_archivo.txt", "r")
    contenido = archivo.read()
    # Procesar el contenido del archivo
    print(contenido)
except FileNotFoundError:
    print("¡Error! El archivo no fue encontrado.")
except Exception as e:
    print(f"Ocurrió otro error: {e}")
finally:
    if archivo is not None:
        archivo.close()
        print("El archivo se ha cerrado.")
                    
                

En este ejemplo, el bloque finally asegura que el archivo se cierre correctamente, ya sea que se haya abierto y leído sin problemas, o si ocurrió una excepción como FileNotFoundError o cualquier otra. Esto es crucial para evitar la pérdida de recursos.

El bloque finally es una herramienta esencial para garantizar la correcta gestión de los recursos en tus programas Python, proporcionando un lugar seguro para ejecutar código de limpieza.

⚠️ Raise an exception

Además de que Python levante excepciones automáticamente cuando ocurren errores, también puedes generar excepciones explícitamente en tu código utilizando la declaración raise.

Esto es útil en situaciones donde quieres indicar que algo inesperado ha ocurrido o que se ha violado una condición específica definida por tu lógica.

Sintaxis de `raise`:

                    raise TipoDeError("Mensaje de error opcional")
                    
                

Puedes levantar cualquier tipo de excepción incorporada en Python o incluso definir tus propias excepciones personalizadas (lo cual veremos en lecciones futuras).

Ejemplo: Levantando una excepción si un valor no es válido

                    def calcular_edad(año_nacimiento):
    if año_nacimiento > 2025:
        raise ValueError("El año de nacimiento no puede ser posterior al año actual.")
    edad = 2025 - año_nacimiento
    return edad

try:
    año = int(input("Introduce tu año de nacimiento: "))
    edad = calcular_edad(año)
    print(f"Tu edad es: {edad}")
except ValueError as e:
    print(f"¡Error! {e}")
                    
                

En este ejemplo, la función calcular_edad verifica si el año de nacimiento es posterior al año actual. Si lo es, levanta una excepción ValueError con un mensaje descriptivo. El bloque try...except captura esta excepción y muestra el mensaje de error al usuario.

Re-levantando una excepción:

Dentro de un bloque except, a veces puedes decidir que no puedes manejar completamente una excepción y necesitas pasarla a un nivel superior para que sea manejada allí. Puedes hacer esto usando raise sin especificar un tipo de excepción:

                    try:
    resultado = 10 / 0
except ZeroDivisionError:
    print("Se intentó dividir por cero.")
    # Realizar alguna acción de limpieza local
    # ...
    raise  # Re-levanta la excepción ZeroDivisionError
                    
                

En este caso, se imprime un mensaje local, se realiza alguna limpieza y luego la excepción original ZeroDivisionError se vuelve a levantar para que pueda ser manejada por un bloque try...except más externo.

La capacidad de levantar excepciones manualmente te da un control significativo sobre el flujo de errores en tu programa, permitiéndote señalar condiciones inesperadas de manera clara y estructurada.




Publicar un comentario

0 Comentarios