Volver a Python Intermedio
Manejo de Excepciones
Las excepciones te permiten manejar errores en tiempo de ejecución de forma elegante en lugar de que el programa se detenga abruptamente.
try / except Básico
try:
resultado = 10 / 0
except ZeroDivisionError:
print("¡No se puede dividir entre cero!")
Múltiples Cláusulas except
def parsear_numero(texto):
try:
return int(texto)
except ValueError:
print(f"'{texto}' no es un número válido")
return None
except TypeError:
print("Se esperaba una cadena, se recibió otra cosa")
return None
else y finally
def leer_archivo(ruta):
try:
with open(ruta, "r") as f:
contenido = f.read()
except FileNotFoundError:
print(f"Archivo no encontrado: {ruta}")
return None
else:
# Solo se ejecuta si no ocurrió excepción
print("¡Archivo leído exitosamente!")
return contenido
finally:
# Siempre se ejecuta
print("Finalizado.")
Lanzar Excepciones
def validar_edad(edad):
if not isinstance(edad, int):
raise TypeError(f"La edad debe ser un entero, se recibió {type(edad).__name__}")
if edad < 0 or edad > 150:
raise ValueError(f"La edad {edad} está fuera del rango válido (0-150)")
return edad
Excepciones Personalizadas
class ErrorApp(Exception):
"""Clase base para errores de la aplicación."""
pass
class ErrorAutenticacion(ErrorApp):
def __init__(self, usuario):
self.usuario = usuario
super().__init__(f"Autenticación fallida para el usuario: {usuario}")
class FondosInsuficientesError(ErrorApp):
def __init__(self, monto, saldo):
self.monto = monto
self.saldo = saldo
super().__init__(
f"No se pueden retirar {monto}. Saldo: {saldo}"
)
# Uso
try:
raise FondosInsuficientesError(500, 100)
except FondosInsuficientesError as e:
print(e) # No se pueden retirar 500. Saldo: 100
print(e.monto) # 500
Encadenamiento de Excepciones
def obtener_datos(url):
try:
import urllib.request
return urllib.request.urlopen(url).read()
except Exception as original:
raise RuntimeError(f"Fallo al obtener {url}") from original
Gestores de Contexto con Excepciones
class ConexionBD:
def __enter__(self):
print("Conectando a la base de datos...")
return self
def __exit__(self, tipo_exc, val_exc, tb_exc):
print("Cerrando conexión.")
if tipo_exc:
print(f"Excepción ocurrida: {val_exc}")
return False # Relanzar la excepción
with ConexionBD() as db:
# ... usar db
pass
Buena práctica: Captura excepciones específicas, no uses
except:sin especificar. Usa excepciones personalizadas para comunicar errores del dominio claramente.