Ejemplos de try/except en Python

Todos los patrones que escribirás de verdad, en el orden en que los necesitarás. La regla que está por encima de las demás: captura el error concreto, no todo.

🎙️ Publicado y grabado:

🎧 Escuchar esta guía

Los patrones básicos

# 1. la estructura habitual
try:
    age = int(user_input)
except ValueError:
    print("that wasn't a number")

# 2. usa el objeto de error
try:
    data = json.loads(text)
except json.JSONDecodeError as e:
    print(f"bad JSON at line {e.lineno}: {e.msg}")

# 3. un tratamiento distinto para cada tipo de error
try:
    resp = requests.get(url, timeout=5)
except requests.Timeout:
    retry()                        # un timeout permite reintentar
except requests.ConnectionError:
    alert_ops()                    # una caída de red, no

# 4. el mismo tratamiento para varios tipos
except (ValueError, KeyError) as e:
    log(e)

else y finally: las cláusulas olvidadas

try:
    f = open(path, encoding="utf-8")
except FileNotFoundError:
    print("no such file")
else:
    # solo se ejecuta si no hay excepción: mantiene mínimo el bloque try
    # y evita capturar por accidente errores de OTRAS líneas
    process(f.read())
    f.close()
finally:
    # se ejecuta PASE LO QUE PASE: aquí va la limpieza
    release_lock()

Lanzar tus propios errores y dejar que sigan subiendo

# rechaza de forma explícita una entrada no válida
def set_age(age):
    if age < 0:
        raise ValueError(f"age can't be negative, got {age}")

# registra y relanza: observa el error sin tragártelo
try:
    charge_card(order)
except PaymentError:
    log_incident(order)
    raise                          # raise sin argumentos = el mismo error sigue subiendo

# excepción propia del dominio (solo es una clase)
class QuotaExceeded(Exception): pass
raise QuotaExceeded("key used 10,000 calls today")

El bucle de reintentos (el patrón que todo el mundo acaba escribiendo)

for attempt in range(3):
    try:
        result = flaky_api_call()
        break                      # éxito → salir del bucle
    except requests.Timeout:
        if attempt == 2:
            raise                  # sin más reintentos → deja que falle de forma visible
        time.sleep(2 ** attempt)   # 1 s, 2 s: espera progresiva
El error que puede acompañarte toda la carrera
except: sin tipo y except Exception: pass se tragan todo: el error tipográfico que acabas de cometer, KeyboardInterrupt y el error real que te tendrá investigando el viernes. El síntoma es «mi código se ejecuta, pero no hace nada». Si de verdad necesitas capturar de forma amplia, por ejemplo en un bucle principal que no puede morir, registra el error completo: except Exception as e: logger.exception(e). Nunca uses pass.
Una opinión sincera
No envuelvas todo en un bloque «por seguridad». Una función que no sabe resolver un error no debería capturarlo. Deja que suba hasta un nivel que pueda decidir: ¿reintentar, avisar al usuario o detenerse? Capturar es una decisión, no un reflejo. Y si el error capturado de verdad no puede ocurrir, elimina el try. Menos ramas, código más honesto.
📚 Esta es una página de nuestra serie de Python. Curso intensivo completo, con audio para el trayecto: Python en 10 minutos →