PythonAprende PythonDocumentación

Errores y excepciones

Maneja fallos con try/except/finally y lanza errores propios con raise.

Los errores son parte del día a día: un archivo que no existe, un usuario que escribe letras donde van números, una división entre cero. Python te da excepciones para manejarlos sin que el programa muera.

Anatomía de un error

print(10 / 0)
# Traceback (most recent call last):
#   File "app.py", line 1, in <module>
# ZeroDivisionError: division by zero

El traceback es tu amigo: léelo de abajo hacia arriba. La última línea dice QUÉ pasó (ZeroDivisionError) y las anteriores dónde.

Las excepciones más comunes

int("hola")              # ValueError → valor inválido para el tipo
lista = [1, 2, 3]
lista[10]                # IndexError → fuera de rango
d = {"a": 1}
d["b"]                   # KeyError → clave inexistente
"texto" + 5              # TypeError → tipos incompatibles
variable_inexistente     # NameError → no está definida

try / except

Captura el error y decide qué hacer:

try:
    numero = int("hola")
except ValueError:
    print("Eso no es un número válido")

print("El programa continúa")   # no murió

Capturar el error específico es la práctica correcta. Un except genérico oculta bugs:

try:
    algo_peligroso()
except Exception:      # MAL: se traga TODO, incluso tus bugs
    pass

try:
    algo_peligroso()
except ValueError as error:   # BIEN: específico, y puedes inspeccionarlo
    print(f"Falló: {error}")

else y finally

try:
    numero = int("42")
except ValueError:
    print("Entrada inválida")
else:
    print(f"Convertido: {numero}")   # solo si NO hubo error
finally:
    print("Esto SIEMPRE se ejecuta") # con o sin error
  • else corre si el try terminó limpio
  • finally corre siempre — ideal para liberar recursos (cerrar archivos, conexiones)

raise: lanzar tus propios errores

Valida entradas y falla temprano con mensajes claros:

def retirar(saldo, monto):
    if monto > saldo:
        raise ValueError(f"Fondos insuficientes: pides {monto}, tienes {saldo}")
    return saldo - monto

try:
    retirar(100, 500)
except ValueError as error:
    print(error)   # Fondos insuficientes: pides 500, tienes 100

El patrón de validación

def leer_edad(texto):
    try:
        edad = int(texto)
    except ValueError:
        return None
    if edad < 0:
        return None
    return edad

print(leer_edad("25"))    # 25
print(leer_edad("abc"))   # None
print(leer_edad("-3"))    # None

Convertir errores en valores manejables (None) mantiene tu programa predecible.

Resumen

  • Lee el traceback de abajo hacia arriba: tipo + mensaje del error
  • try/except captura errores específicos (ValueError, KeyError...)
  • else corre si todo salió bien; finally corre siempre
  • raise ValueError("mensaje") lanza errores propios con contexto
  • Nunca uses except: desnudo — te oculta los bugs

Quiz

  1. 1. ¿Qué excepción se lanza al dividir entre cero?

  2. 2. ¿Cuándo se ejecuta el bloque `else` de un try/except?

  3. 3. ¿Para qué sirve la instrucción `raise`?

Ejercicios

Ejercicio 1: División segura

Completa la función para que devuelva el resultado de a / b, pero devuelva None si b es cero (captura ZeroDivisionError con try/except).

Cargando editor…

Ejercicio 2: Validación con raise

Completa la función para que lance ValueError con el mensaje "edad negativa" si edad < 0, y devuelva "ok" en caso contrario.

Cargando editor…