Excepciones en Python
Aprendé a manejar errores de forma elegante con try, except, else y finally. Los errores son parte del software — lo importante es saber cómo tratarlos.
¿Qué es una excepción?
Cuando Python encuentra un error en tiempo de ejecución, lanza una excepción. Si no la manejás, el programa se detiene con un mensaje de error.
# Sin manejo de errores — el programa explota
numero = int("hola") # ValueError
lista = [1, 2, 3]
print(lista[10]) # IndexError
resultado = 10 / 0 # ZeroDivisionError
Con try / except podés atrapar esas excepciones y decidir qué hacer.
try:
numero = int("hola")
except ValueError:
print("Eso no es un número válido")
En Python, los errores de sintaxis (SyntaxError) ocurren antes de ejecutar el código. Las excepciones ocurren durante la ejecución. El bloque try/except solo maneja excepciones, no errores de sintaxis.
Estructura completa: try / except / else / finally
try:
# Código que puede fallar
resultado = 10 / 2
except ZeroDivisionError:
# Se ejecuta si ocurre ese error específico
print("No se puede dividir por cero")
else:
# Se ejecuta si NO hubo ninguna excepción
print(f"Resultado: {resultado}")
finally:
# Se ejecuta SIEMPRE, haya error o no
print("Operación finalizada")
try
Código que puede fallar
Si falla, salta al except
except
Manejar el error
Se ejecuta si hubo excepción
else
Todo salió bien
Solo si no hubo excepción
finally
Siempre se ejecuta
Ideal para liberar recursos
Excepciones más comunes
| Excepción | Cuándo ocurre | Ejemplo |
|---|---|---|
ValueError | Valor incorrecto para la operación | int("hola") |
TypeError | Tipo de dato incorrecto | "2" + 2 |
ZeroDivisionError | División por cero | 10 / 0 |
IndexError | Índice fuera de rango | [1,2,3][10] |
KeyError | Clave no existe en dict | d["x"] |
FileNotFoundError | Archivo no encontrado | open("x.txt") |
AttributeError | Atributo inexistente | None.upper() |
NameError | Variable no definida | print(x) |
Capturar múltiples excepciones
def dividir(a, b):
try:
return a / b
except ZeroDivisionError:
print("Error: no se puede dividir por cero")
except TypeError:
print("Error: los argumentos deben ser números")
return None
# También podés capturar varias en una sola línea
try:
resultado = int(input_dato) / divisor
except (ValueError, ZeroDivisionError) as e:
print(f"Error: {e}")
Obtener información del error
try:
numero = int("abc")
except ValueError as e:
print(f"Tipo de error : {type(e).__name__}")
print(f"Mensaje : {e}")
# Capturar cualquier excepción (usar con cuidado)
try:
resultado = 10 / 0
except Exception as e:
print(f"Ocurrió un error: {e}")
Usar except: sin especificar el tipo atrapa incluso errores del sistema como KeyboardInterrupt. Siempre que puedas, especificá el tipo de excepción que esperás.
Lanzar excepciones con raise
Podés lanzar tus propias excepciones para validar datos en funciones:
def calcular_descuento(precio, porcentaje):
if precio < 0:
raise ValueError("El precio no puede ser negativo")
if not 0 <= porcentaje <= 100:
raise ValueError("El porcentaje debe estar entre 0 y 100")
return precio * (1 - porcentaje / 100)
try:
print(calcular_descuento(100, 20)) # 80.0
print(calcular_descuento(-50, 10)) # ValueError
except ValueError as e:
print(f"Error de validación: {e}")
Ejemplo Completo
Conversor de datos con manejo robusto de errores:
def convertir_a_numero(texto):
"""Intenta convertir un string a int o float."""
try:
return int(texto)
except ValueError:
try:
return float(texto)
except ValueError:
raise ValueError(f"'{texto}' no es un número válido")
def procesar_datos(datos):
"""Procesa una lista de strings y convierte los que pueda."""
resultados = []
errores = []
for item in datos:
try:
num = convertir_a_numero(item.strip())
resultados.append(num)
except ValueError as e:
errores.append({"valor": item, "error": str(e)})
return resultados, errores
# Datos con mezcla de válidos e inválidos
entradas = ["42", "3.14", "hola", "100", "", "7", "???"]
numeros, problemas = procesar_datos(entradas)
print(f"Convertidos ({len(numeros)}): {numeros}")
print(f"Suma de válidos : {sum(numeros):.2f}")
if problemas:
print(f"\nErrores ({len(problemas)}):")
for p in problemas:
print(f" '{p['valor']}' → {p['error']}")
Probá el Ejemplo 3: Conversor de datos
Buenas Prácticas
- Específico antes que general — capturá
ValueErrorantes queException - No silencies errores — un
except: passvacío oculta problemas reales - Usá finally para liberar recursos — cerrar archivos, conexiones, etc.
- raise para validar entradas — mejor fallar temprano con un mensaje claro
- Logueá los errores — en producción, registrá los errores en vez de solo imprimirlos
- Mensajes descriptivos —
"El precio no puede ser negativo"es mejor que"Error"