Excepciones
Anticipa y gestiona los errores en tus programas
Gestión de excepciones en Python
Las excepciones son eventos que se producen durante la ejecución de un programa y que alteran el flujo normal de instrucciones. En Python, las excepciones son objetos que representan errores. La gestión de excepciones es crucial para desarrollar aplicaciones robustas que puedan afrontar situaciones imprevistas sin fallar.
En este tutorial vamos a explorar cómo identificar, gestionar y crear excepciones en Python.
¿Por qué gestionar las excepciones?
La gestión de excepciones es importante por varias razones:
- Robustez: Un programa que gestiona correctamente las excepciones puede seguir funcionando incluso cuando se producen errores.
- Experiencia de usuario: Mostrar mensajes de error amigables en lugar de trazas de error técnicas.
- Depuración: Obtener información detallada sobre el error para facilitar su corrección.
- Gestión de recursos: Asegurarse de que los recursos (archivos, conexiones de red, etc.) se liberan correctamente, incluso en caso de error.
Tipos de excepciones habituales en Python
Python incluye numerosos tipos de excepciones integrados. Estos son algunos de los más habituales:
SyntaxError: Error en la sintaxis del código.NameError: Intento de usar una variable no definida.TypeError: Operación o función aplicada a un objeto de tipo inadecuado.ValueError: Operación o función que recibe un argumento del tipo correcto pero con un valor inadecuado.IndexError: Intento de acceder a un índice que no existe en una secuencia.KeyError: Intento de acceder a una clave que no existe en un diccionario.FileNotFoundError: Intento de abrir un archivo que no existe.ZeroDivisionError: División por cero.ImportError: Fallo al importar un módulo.IOError: Error de entrada/salida (por ejemplo, al leer un archivo).AttributeError: Intento de acceder a un atributo inexistente.
Estructura try-except-else-finally
Python utiliza los bloques try, except, else y finally para gestionar las excepciones.
Estructura básica try-except
try:
# Código susceptible de generar una excepción
resultat = 10 / 0
except ZeroDivisionError:
# Código que se ejecuta si se produce una ZeroDivisionError
print("Erreur : Division par zéro !")
En este ejemplo, cuando 10 / 0 genera una ZeroDivisionError, se ejecuta el bloque except correspondiente.
Capturar varios tipos de excepciones
Puedes capturar distintos tipos de excepciones con manejadores independientes:
try:
# Código susceptible de generar excepciones
nombre = int(input("Entrez un nombre : "))
resultat = 10 / nombre
except ValueError:
# Se ejecuta si la entrada no es un número válido
print("Erreur : Veuillez entrer un nombre valide.")
except ZeroDivisionError:
# Se ejecuta si nombre == 0
print("Erreur : La division par zéro n'est pas autorisée.")
También puedes capturar varias excepciones con el mismo manejador:
try:
# Código susceptible de generar excepciones
nombre = int(input("Entrez un nombre : "))
resultat = 10 / nombre
except (ValueError, ZeroDivisionError):
# Se ejecuta si se produce alguna de las excepciones mencionadas
print("Erreur : Entrée invalide ou division par zéro.")
Capturar todas las excepciones
Aunque por lo general no se recomienda (porque puede ocultar errores inesperados), es posible capturar todas las excepciones:
try:
# Código susceptible de generar cualquier excepción
# ...
except Exception as e:
# Se ejecuta para cualquier excepción que herede de Exception
print(f"Une erreur s'est produite : {e}")
Bloque else
El bloque else se ejecuta si no se lanza ninguna excepción en el bloque try:
try:
nombre = int(input("Entrez un nombre : "))
resultat = 10 / nombre
except ValueError:
print("Entrée invalide.")
except ZeroDivisionError:
print("Division par zéro.")
else:
# Este bloque se ejecuta si no se lanza ninguna excepción
print(f"Le résultat est {resultat}")
Bloque finally
El bloque finally se ejecuta pase lo que pase, se lance o no una excepción:
try:
fichier = open("donnees.txt", "r")
# Operaciones sobre el archivo
except FileNotFoundError:
print("Le fichier n'existe pas.")
finally:
# Este bloque se ejecuta siempre
# Ideal para liberar recursos
if 'fichier' in locals():
fichier.close()
print("Fichier fermé.")
El bloque finally es especialmente útil para asegurarse de que los recursos se liberan correctamente, incluso en caso de error.
Lanzar excepciones
Puedes lanzar (o “throw”) excepciones de forma deliberada mediante la instrucción raise:
def diviser(a, b):
if b == 0:
raise ZeroDivisionError("Division par zéro non autorisée")
return a / b
try:
resultat = diviser(10, 0)
except ZeroDivisionError as e:
print(f"Erreur : {e}")
Crear excepciones personalizadas
Puedes crear tus propios tipos de excepciones heredando de la clase Exception o de una de sus subclases:
class ValeurNegativeError(Exception):
"""Excepción lanzada cuando se utiliza un valor negativo que no debería serlo."""
pass
def calculer_racine_carree(nombre):
if nombre < 0:
raise ValeurNegativeError("La racine carrée d'un nombre négatif n'est pas définie pour les nombres réels.")
import math
return math.sqrt(nombre)
try:
resultat = calculer_racine_carree(-1)
except ValeurNegativeError as e:
print(f"Erreur : {e}")
Aserciones
Las aserciones son comprobaciones de depuración que verifican si una condición es verdadera. Si la condición es falsa, se lanza una excepción AssertionError:
def diviser(a, b):
assert b != 0, "Le diviseur ne peut pas être zéro"
return a / b
try:
resultat = diviser(10, 0)
except AssertionError as e:
print(f"Assertion échouée : {e}")
Las aserciones se utilizan principalmente para la depuración y las pruebas, y pueden desactivarse en modo de producción.
Con la instrucción with
La instrucción with se utiliza para garantizar que los recursos se gestionan correctamente, incluso en caso de excepción. Es una forma más limpia de gestionar las excepciones en operaciones que requieren recursos como los archivos:
try:
with open("fichier.txt", "r") as fichier:
contenu = fichier.read()
# El archivo se cierra automáticamente al final del bloque with,
# incluso si se lanza una excepción
except FileNotFoundError:
print("Le fichier n'existe pas.")
Jerarquía de excepciones
Las excepciones en Python forman una jerarquía. Esta es una versión simplificada de dicha jerarquía:
BaseExceptionExceptionArithmeticErrorZeroDivisionErrorOverflowError
LookupErrorIndexErrorKeyError
OSErrorFileNotFoundErrorPermissionError
TypeErrorValueError- …
SystemExitKeyboardInterrupt- …
Cuando capturas excepciones, el orden es importante. Si tienes varios bloques except, Python los comprueba en orden. Si una excepción es una subclase de otra que ya has capturado, nunca se llegará a ella:
try:
# Código susceptible de generar excepciones
# ...
except Exception:
# Este bloque capturará todas las excepciones que heredan de Exception
print("Une exception s'est produite")
except ZeroDivisionError:
# Este bloque NUNCA se alcanzará porque ZeroDivisionError es una subclase de Exception
print("Division par zéro")
Para evitar este problema, coloca las excepciones más específicas antes que las más generales.
Buenas prácticas en la gestión de excepciones
-
Sé específico: Captura excepciones específicas en lugar de utilizar un
exceptgenérico. -
No suprimas los errores en silencio: Evita capturar una excepción sin gestionarla correctamente o sin dejar constancia de ella.
-
Utiliza
finallypara la limpieza: Utiliza el bloquefinallypara asegurarte de que los recursos se liberan correctamente. -
Crea excepciones personalizadas cuando sea apropiado: Esto puede hacer que tu código sea más legible y permitir una gestión más precisa de los errores.
-
Mantén los bloques try pequeños: Incluye en el bloque
tryúnicamente el código susceptible de generar la excepción. -
Registra las excepciones en el log: En las aplicaciones de producción, conviene guardar las excepciones en archivos de log.
Conclusión
La gestión eficaz de las excepciones es una competencia esencial para cualquier programador de Python. Te permite escribir programas robustos que pueden gestionar los errores de forma elegante.
En este tutorial hemos explorado cómo identificar, capturar y lanzar excepciones, cómo crear tus propios tipos de excepciones y cómo utilizar la instrucción with para gestionar los recursos. También hemos comentado las buenas prácticas para una gestión eficaz de las excepciones.
En el próximo tutorial abordaremos la manipulación de archivos en Python, un ámbito en el que la gestión de excepciones es especialmente importante.
Comentarios
Los comentarios funcionan con GitHub Discussions
Inicia sesión con GitHub para participar en la discusión