Aprende leyendo en orden

Capturar excepciones con try / except

Aprende el manejo de excepciones en Python con try / except / finally para capturar y limpiar errores con elegancia.

try / except es el mecanismo que captura los errores lanzados en tiempo de ejecución y mantiene tu programa en marcha en lugar de dejarlo caer. Úsalo para operaciones que se espera que fallen a veces — obtención de datos externos, validación de la entrada del usuario, operaciones de archivo, y así.

Errores de sintaxis vs. errores de tiempo de ejecución

Python tiene dos grandes tipos de errores. Los errores de sintaxis ocurren cuando el código viola la gramática de Python y se detectan antes de que el programa se ejecute. Los errores de tiempo de ejecución (excepciones) son gramaticalmente correctos pero surgen mientras el programa se ejecuta. Solo los errores de tiempo de ejecución se pueden capturar con try / except.

Errores de sintaxis vs. errores de tiempo de ejecución
Error de PythonError de sintaxis(detectado antes)Error en ejecución(lanzado al correr)El programa nunca arrancatry no puede capturarloSe puede capturarcon try / exceptfalta dos puntosdivisión por cero

Los errores de sintaxis se detectan en el momento en que Python lee el código, así que el programa nunca se ejecuta. Los errores de tiempo de ejecución solo se disparan cuando la ejecución realmente llega a esa línea — por eso try / except puede interceptarlos.

# Error de sintaxis: faltan los dos puntos. Falla antes de que la línea llegue a ejecutarse
# if x > 0
#     print("positivo")

# Error en tiempo de ejecución: gramaticalmente correcto, pero falla al ejecutarse
x = 100
print(x / 0)   # ZeroDivisionError: division by zero
print("esta línea nunca se ejecuta")

Cuando se lanza un error en tiempo de ejecución, todo lo que hay después de esa línea se salta. Ejecuta el siguiente fragmento y verás que el print() final no se dispara — el programa se detiene en IndexError.

# Confirmando un error en tiempo de ejecución: sin try, el programa se detiene
numbers = [10, 20, 30]
print(numbers[10])       # IndexError: list index out of range
print("esta línea nunca se ejecuta")
# Salida:
# Traceback (most recent call last):
#   File "...", line 3, in <module>
# IndexError: list index out of range

Lo básico de try / except

Pon el código arriesgado en el bloque try: y el código de recuperación en un bloque except ClaseDeError:.

En el instante en que se dispara un error en try, el resto del cuerpo de try se salta y el control salta al except que coincide. El código después de except sigue ejecutándose incluso cuando ocurre un error.

Cómo fluye try / except
ejecutar cuerpo try¿se disparó un error?sin error(llegó al final)error lanzado(resto saltado)se salta exceptejecutarexcept coincidentecontinuarcon el restoNocoincide

Ejecuta el cuerpo de try. Si no se lanza ninguna excepción, el except se salta y el control pasa al resto del programa. Si se dispara una excepción, el resto del cuerpo de try se salta, se ejecuta el except que coincide, y después el control continúa.

# Envolverlo en try mantiene el programa en marcha incluso cuando se dispara división por cero
a = 100
try:
    result = a / 0
    print(result)                # nunca se alcanza
except ZeroDivisionError:
    print("No se puede dividir entre 0")  # el control salta aquí

print("después del bloque try")   # siempre se ejecuta tras try / except
# Salida: No se puede dividir entre 0
#        después del bloque try

Protégete contra el acceso a un índice fuera de rango en una lista de stock.

① Define stock = [12, 8, 3] (cantidad en cada estante).

② Primero confirma qué ocurre si llamas a stock[5] sin try. La respuesta deja esta línea como comentario; descoméntala para ver el programa detenerse con IndexError.

③ Ahora ejecuta print(stock[5]) dentro de try e imprime "Ese estante no existe" desde except IndexError:.

④ Después de try / except, imprime "Continuando…" para confirmar que la ejecución se reanuda incluso después de la excepción.

(La explicación aparece una vez que ejecutes el código correctamente.)

Editor Python

Ejecutar el código para ver el resultado

Capturar el objeto de excepción con as e

Escribir except ClaseDeError as e: pone los detalles de la excepción en e. print(e) muestra el mensaje de error, y type(e) muestra la clase del error. Registrar estos datos es un buen punto de partida para rastrear problemas más tarde.

user_input = "abc"   # se esperaba un número, pero llegó una cadena

try:
    value = int(user_input)
except ValueError as e:
    print("La entrada no es numérica")
    print(f"Detalles: {e}")
    print(f"Tipo: {type(e).__name__}")
# Salida: La entrada no es numérica
#        Detalles: invalid literal for int() with base 10: 'abc'
#        Tipo: ValueError
Qué puedes extraer del objeto de excepción
se dispara errorint("abc")except ValueError as eobjeto de excepción estr(e)→ mensajetype(e).__name__→ nombre de clasetraceback.format_exc()→ traza de pilaasignar

El mensaje por sí solo no te dice dónde se lanzó el error, así que durante la depuración es estándar acompañarlo con import traceback. traceback.format_exc() devuelve la ruta de llamada (traza de pila) en el momento en que se disparó la excepción, y registrar eso hace el análisis de causa raíz mucho más fácil.

import traceback

try:
    value = int("abc")
except ValueError as e:
    print(f"Detalles: {e}")
    print(f"Tipo: {type(e).__name__}")
    print("--- traceback ---")
    print(traceback.format_exc())
# Salida:
# Detalles: invalid literal for int() with base 10: 'abc'
# Tipo: ValueError
# --- traceback ---
# Traceback (most recent call last):
#   File "...", line 4, in <module>
#     value = int("abc")
# ValueError: invalid literal for int() with base 10: 'abc'

Cuando la entrada del usuario no se puede convertir a número, imprime el mensaje, el tipo y la traza de pila juntos.

① Al principio, escribe import traceback y define user_input = "Madrid".

② En try, llama a int(user_input), y captúralo con except ValueError as e:.

③ Dentro de except, imprime "Mensaje: {e} / Tipo: {type(e).__name__}" en una línea, y luego print(traceback.format_exc()).

Editor Python

Ejecutar el código para ver el resultado

Varios bloques except y el paraguas Exception

Puedes apilar varios bloques except sobre un único try. Se ejecuta el que coincida primero, así que la forma idiomática es listarlos de lo más específico a lo más general.

Todos los errores de tiempo de ejecución heredan de Exception, así que except Exception as e: captura cualquier cosa, incluidos los errores inesperados.

Ordena los except de específico a general
error en el cuerpo tryexcept¿IndexError?ejecutar manejadorIndexErrorexcept¿ZeroDivisionError?ejecutar manejadorZeroDivisionErrorexcept¿Exception?captura totalpara imprevistoscontinuardespués de trycoincideno coincidecoincideno coincidecoincide
numbers = [10, 20, 30]
index = 1
divisor = 0

try:
    value = numbers[index]
    print(value / divisor)
except IndexError as e:
    print(f"Índice fuera de rango: {e}")
except ZeroDivisionError as e:
    print(f"No se puede dividir entre 0: {e}")
except Exception as e:
    print(f"Otro error: {type(e).__name__}: {e}")
# Salida: No se puede dividir entre 0: division by zero

No pongas Exception primero

Exception es el padre de casi todas las excepciones, así que ponerlo arriba impide que cualquier except posterior más específico se ejecute. Úsalo como la última red de seguridad para errores inesperados.

Saca una cantidad de artículos del historial de compras de un usuario, súmalos y calcula el promedio.

① Define history = [1200, 800, 1500] (montos de compra) y take = 10 (número a tomar).

② Dentro de try, calcula total = sum(history[:take]), luego avg = total / len(history[:take]) y print(f"Promedio: {avg}").

③ Añade una captura total: except ZeroDivisionError as e: imprime "Sin datos", y except Exception as e: imprime "Inesperado: {e}". (En el camino feliz el promedio se imprime normalmente.)

Editor Python

Ejecutar el código para ver el resultado

Ejecutar limpieza con finally

El bloque finally: es el hueco de limpieza que siempre se ejecuta, se dispare o no una excepción. Úsalo para liberar recursos que deben cerrarse — archivos, conexiones a BD, y así.

El bloque else: se ejecuta solo cuando no se lanzó ninguna excepción. No se usa tan a menudo, pero hace explícito el camino de «solo si hubo éxito, sigue».

Orden de ejecución de try / except / else / finally
ejecutar cuerpo try¿se disparóuna excepción?bloque else(solo éxito)bloque except(manejarla)bloque finally(siempre corre)continuar con el restoNo (éxito)Sí (falló)

Después de que corra try: sin excepción → ir a else, con excepción → ir al except que coincida. De cualquier manera, finally siempre se ejecuta al final — esa es la clave.

# Camino feliz: se ejecutan else y finally
a, b = 10, 2
try:
    result = a / b
except ZeroDivisionError:
    print("Capturada división por cero")
else:
    print(f"Éxito: {result}")
finally:
    print("Ejecutando limpieza")
# Salida: Éxito: 5.0
#        Ejecutando limpieza

print("---")

# Camino de error: se ejecutan except y finally
a, b = 10, 0
try:
    result = a / b
except ZeroDivisionError:
    print("Capturada división por cero")
else:
    print(f"Éxito: {result}")
finally:
    print("Ejecutando limpieza")
# Salida: Capturada división por cero
#        Ejecutando limpieza

Simula una llamada a una API y registra éxito, fallo y limpieza en cada camino.

① Define user_ids = [101, 102, 103] y target = 0.

② En try, toma user = user_ids[target] (no hagas print todavía).

③ En except IndexError:, imprime "Usuario no existe".

④ En else:, imprime f"Obtenido: {user}" para que se ejecute solo cuando no se haya lanzado ninguna excepción.

⑤ En finally:, imprime "Conexión cerrada" para que se ejecute en ambos caminos.

Editor Python

Ejecutar el código para ver el resultado

En este artículo aprendiste los fundamentos del manejo de excepciones con try / except, cómo capturar información de la excepción con as e, cómo apilar varios bloques except y usar Exception como captura total, y cómo ejecutar limpieza con finally. A continuación: lanzar excepciones tú mismo con raise, y definir clases de excepción personalizadas.

QUIZ

Verificación de conocimientos

Responde cada pregunta una a una.

Pregunta 1¿Cuál de estos es un ejemplo de error de sintaxis?

Pregunta 2¿Qué imprime el siguiente código?
a = 100
try:
print(a / 0)
except ZeroDivisionError:
print("capturado")
print("fin")

Pregunta 3De try / except / else / finally, ¿cuál siempre se ejecuta sin importar si se lanzó una excepción?