Excepciones y errores
Los errores son inevitables: archivos que no existen, datos con formato incorrecto, divisiones por
cero. La diferencia entre código amateur y profesional es cómo manejás esos errores. Con
try/except, tu programa reacciona en vez de explotar.
Concepto teórico
¿Qué es una excepción?
Una excepción es un error que ocurre durante la ejecución del programa. Cuando Python encuentra un error, crea un objeto de excepción con información sobre qué salió mal. Si no lo "atrapás", el programa se detiene y muestra un traceback (la cadena de llamadas que llevó al error).
Tipos de errores comunes
| Error | Cuándo ocurre | Ejemplo |
|---|---|---|
SyntaxError |
Código mal escrito (se detecta ANTES de ejecutar) | if x = 5: (falta ==) |
NameError |
Variable o función no definida | print(xyz) sin definir xyz |
TypeError |
Operación con tipo incorrecto | "5" + 3 (str + int) |
ValueError |
Valor incorrecto para el tipo | int("abc") |
IndexError |
Índice fuera de rango | lista[100] en lista de 5 |
KeyError |
Clave no existe en diccionario | d["inexistente"] |
ZeroDivisionError |
División por cero | 10 / 0 |
FileNotFoundError |
Archivo no existe | open("no_existe.csv") |
AttributeError |
Método/atributo no existe | "hola".appendd() |
try / except / else / finally
try:
# código que PUEDE fallar
resultado = int(dato)
except ValueError:
# se ejecuta SOLO si hay ValueError
print("Dato no es un número")
except (TypeError, KeyError) as e:
# capturar múltiples tipos
print(f"Error: {e}")
else:
# se ejecuta SOLO si NO hubo excepción
print(f"Conversión exitosa: {resultado}")
finally:
# se ejecuta SIEMPRE (haya o no error)
print("Proceso terminado")
except:
o except Exception: captura TODO, incluyendo errores que necesitás ver (como bugs en tu
código). Siempre capturá el tipo de error específico que esperás: except ValueError:,
except FileNotFoundError:, etc.
try: ... except: pass. Esto silencia
TODOS los errores. Tu programa "funciona" pero produce resultados incorrectos sin avisarte. Es el
equivalente a tapar la luz de "check engine" con cinta. NUNCA uses except: pass.raise — lanzar excepciones propias
raise te permite lanzar excepciones explícitamente cuando tu código detecta una condición
inválida:
def depositar(saldo, monto):
if monto <= 0:
raise ValueError(f"Monto debe ser positivo, recibí: {monto}")
return saldo + monto
EAFP vs LBYL
Dos filosofías para manejar errores:
- LBYL (Look Before You Leap — mirá antes de saltar): verificá las condiciones ANTES de actuar.
if "score" in dict: usar dict["score"] - EAFP (Easier to Ask Forgiveness than Permission — mejor pedir perdón que permiso): intentá
directamente y capturá el error si falla.
try: usar dict["score"] except KeyError: manejar
Python favorece EAFP. Es más pythónico, más eficiente (si el error es raro) y evita condiciones de carrera.
try/except ValueError te permite procesar miles de registros atrapando los errores uno a
uno sin que todo el pipeline se caiga.
Ejemplos explicados paso a paso
Ejemplo 1: try/except básico
Hacé clic en ▶ Ejecutar
Ejemplo 2: Capturar múltiples tipos de error
Hacé clic en ▶ Ejecutar
Ejemplo 3: raise y validación de datos
Hacé clic en ▶ Ejecutar
Ejemplo 4: Pipeline robusto con manejo de errores
Hacé clic en ▶ Ejecutar
Ejemplo 5: EAFP vs LBYL y excepciones custom
Hacé clic en ▶ Ejecutar
Referencia rápida
| Bloque | Cuándo se ejecuta | Obligatorio |
|---|---|---|
try |
Siempre (código que puede fallar) | Sí |
except TipoError |
Solo si ocurre ese tipo de error | Sí (al menos uno) |
else |
Solo si NO hubo error | No |
finally |
SIEMPRE (haya o no error) | No |
| Buena práctica | Mala práctica |
|---|---|
except ValueError: (específico) |
except: (captura TODO) |
| Loggear el error | except: pass (silenciar) |
raise para datos inválidos |
Devolver None o -1 silenciosamente |
| EAFP (try/except) | LBYL excesivo (if anidados) |
| Excepciones custom descriptivas | Mensajes genéricos "Error" |
Ejercicios
Ejercicio 1: try/except con ValueError
Intentá convertir "abc" a int. Capturá el error e imprimí un mensaje amigable. Debe
incluir no es un número.
Hacé clic en ▶ Ejecutar
Ejercicio 2: Capturar ZeroDivisionError
Creá una función dividir(a, b) que devuelva a/b o None si b es
0. Debe incluir None.
Hacé clic en ▶ Ejecutar
Ejercicio 3: KeyError con .get() o try/except
Dado un dict sin clave "email", accedé de forma segura con try/except. Debe incluir
no disponible.
Hacé clic en ▶ Ejecutar
Ejercicio 4: Convertir lista con errores
Dada ["42","3.14","abc","100","","N/A","55"], convertí a float los que se pueda, contá
los errores. Debe incluir errores: 3.
Hacé clic en ▶ Ejecutar
Ejercicio 5: raise para validación
Creá validar_monto(monto) que lance ValueError si es negativo o
TypeError si no es número. Debe incluir ValueError.
Hacé clic en ▶ Ejecutar
Ejercicio 6: try/except/else/finally completo
Creá una función que intente abrir un archivo, lo lea si existe, use else para confirmar éxito y
finally para registrar que terminó. Debe incluir finally.
Hacé clic en ▶ Ejecutar
Ejercicio 7: Pipeline robusto
Procesá ["García|720|$150,000","López|abc|$320,000","Pérez|810|$890,000"] con try/except
capturando errores por línea sin detener el pipeline. Debe incluir procesados.
Hacé clic en ▶ Ejecutar
Ejercicio 8: Excepción custom
Creá class SaldoInsuficienteError(Exception) que se lance cuando intentás extraer más de
lo que hay. Debe incluir SaldoInsuficiente.
Hacé clic en ▶ Ejecutar
Ejercicio 9: Retry pattern
Creá una función operar_con_retry(func, max_intentos=3) que reintente una operación
hasta N veces si falla. Simulá una operación que falla aleatoriamente. Debe incluir
intento.
Hacé clic en ▶ Ejecutar
Ejercicio 10: Sistema de procesamiento con logging de errores
Procesá 6 registros crudos: parseá, validá (score 0-999, saldo positivo), guardá los válidos en un
JSON y los errores en un log. Debe incluir RESULTADO.
Hacé clic en ▶ Ejecutar
Resumen y conexión
try/exceptcaptura errores sin detener el programa.elsese ejecuta si no hubo error.finallysiempre.- SIEMPRE capturá excepciones específicas (
except ValueError), nunca genéricas (except:). raiselanza excepciones cuando tus datos son inválidos.- NUNCA uses
except: pass— silencia bugs sin avisarte. - Python favorece EAFP (try/except) sobre LBYL (if anidados).
- Las excepciones custom (
class MiError(Exception)) hacen tu código más expresivo.
En la siguiente lección (26 · Clases y objetos intro) vas a aprender programación orientada a objetos: crear clases, instancias, métodos y herencia básica.
Recursos: Python docs — Errors · Built-in Exceptions