Volver a la lista

Manejo de excepciones en Python: try, except, raise

Aprende todo sobre el manejo de excepciones en Python: capturarlas, generarlas y limpiar recursos, con ejemplos prácticos.

Intermedio
|
10min
|
Verificado (2026-07)
manejo de excepcionestry-exceptraisefinallymanejo de errores
Progreso0/18 (0%)

Manejo de excepciones en Python — try, except, raise

Al finalizar este tema

Comprenderá el principio subyacente a la aparición de errores en Python, aprenderá a capturarlos mediante try/except, generar errores directamente con raise y realizar tareas de limpieza utilizando finally.


Los errores detienen el programa

En Python, cuando ocurre un error, el programa se detiene inmediatamente.

python
numbers = [1, 2, 3]
print(numbers[10]) # IndexError: list index out of range
print("This line never runs")

Si se produce un error, todo el código posterior no se ejecuta. En un servidor web, el propio servidor puede dejar de funcionar. En un script de análisis de datos, podrías procesar 999 de cada 1000 registros, pero uno solo provoca que falle todo el proceso.

El manejo de excepciones es "la forma de responder sin detenerse cuando ocurre un error".


try/except — Capturar errores

python
try:
result = 10 / 0
except ZeroDivisionError:
print("No se puede dividir entre cero")
print("El programa continúa") # ¡Esta línea se ejecuta!

Si ocurre un error dentro del bloque try, el programa salta al bloque except. El programa continúa ejecutándose sin detenerse.

Obtener mensaje de error

python
try:
value = int("hello")
except ValueError as e:
print(f"Error: {e}") # Error: invalid literal for int() with base 10: 'hello'

Al recibir un objeto de error con as e, puedes verificar qué salió mal.

Manejo individual de cada error

python
def safe_divide(a, b):
try:
result = a / b
return round(result, 2)
except ZeroDivisionError:
print("Denominator cannot be zero")
return None
except TypeError:
print("Both arguments must be numbers")
return None
safe_divide(10, 0) # Denominator cannot be zero
safe_divide("10", 2) # Both arguments must be numbers
safe_divide(10, 3) # 3.33

Puede manejar diferentes tipos de errores con respuestas distintas. Aunque es posible capturar todos los errores de una vez con except Exception, no se recomienda hacerlo, ya que sin saber qué tipo de error ocurrió, la depuración se vuelve difícil.


Tipos de errores comunes

ErrorCausaEjemplo
ValueErrorValor incorrectoint("abc")
TypeErrorTipo incorrecto"3" + 5
IndexErrorÍndice fuera de rango[1,2,3][10]
KeyErrorClave no encontrada en el diccionario{"a": 1}["b"]
FileNotFoundErrorArchivo no encontradoopen("none.txt")
ZeroDivisionErrorDivisión por cero10 / 0
AttributeErrorAcceso a atributo/método inexistenteNone.upper()

Estos siete son los errores más comunes que se encuentran en el día a día.


else y finally

python
try:
f = open("data.txt", "r")
content = f.read()
except FileNotFoundError:
print("File not found")
else:
# Se ejecuta solo si try tiene éxito
print(f"Read {len(content)} characters")
finally:
# Se ejecuta siempre, haya éxito o fallo
print("Cleanup done")
BloqueMomento de ejecución
trySiempre se intenta
exceptCuando ocurre un error
elseCuando tiene éxito sin errores
finallySin importar el resultado (tanto en éxito como en fallo)

finally se utiliza para tareas de limpieza como cerrar archivos, finalizar conexiones de red y eliminar archivos temporales. Es código que debe ejecutarse obligatoriamente, independientemente de si ocurre un error o no.


raise — Generar un error directamente

python
def withdraw(balance, amount):
if amount <= 0:
raise ValueError("Withdrawal amount must be positive")
if amount > balance:
raise ValueError(f"Insufficient funds: balance={balance}, requested={amount}")
return balance - amount
try:
new_balance = withdraw(1000, 5000)
except ValueError as e:
print(f"Transaction failed: {e}")
# Transaction failed: Insufficient funds: balance=1000, requested=5000

raise es declarar "esta situación no es normal". Transfiere la responsabilidad al llamador para que lo maneje mediante try/except.

Clase de error personalizada

python
class InsufficientFundsError(Exception):
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(
f"Cannot withdraw {amount} from balance {balance}"
)
def withdraw(balance, amount):
if amount > balance:
raise InsufficientFundsError(balance, amount)
return balance - amount
try:
withdraw(1000, 5000)
except InsufficientFundsError as e:
print(e) # Cannot withdraw 5000 from balance 1000
print(e.balance) # 1000
print(e.amount) # 5000

Exception se puede heredar para crear tus propios errores. Puedes incluir información adicional (saldo, monto de la solicitud) en el error, lo que permite que quien lo capture pueda manejarlo con mayor precisión.


Patrón práctico — Procesamiento de archivos

python
def read_config(filepath):
try:
with open(filepath, "r", encoding="utf-8") as f:
lines = f.readlines()
except FileNotFoundError:
print(f"Config file not found: {filepath}")
return {}
except PermissionError:
print(f"Permission denied: {filepath}")
return {}
config = {}
for i, line in enumerate(lines, 1):
line = line.strip()
if not line or line.startswith("#"):
continue
if "=" not in line:
print(f"Warning: invalid format at line {i}: {line}")
continue
key, value = line.split("=", 1)
config[key.strip()] = value.strip()
return config
# config.txt:
# host = localhost
# port = 3000
# # this is a comment
settings = read_config("config.txt")
print(settings) # {'host': 'localhost', 'port': '3000'}

Este patrón se utiliza con mucha frecuencia en la práctica:

  1. Manejar el fallo al abrir un archivo como except
  2. Emitir solo una advertencia y omitir las filas incorrectas durante el análisis
  3. Ignorar las líneas vacías y los comentarios (#)

En lugar de que el programa falle simplemente por no poder abrir un archivo de configuración, este opera con valores predeterminados o muestra una advertencia.


Antipatrón — Lo que no se debe hacer

Ignorar todos los errores

python
# Mal — se traga el error
try:
risky_operation()
except Exception:
pass # What happened? Nobody knows
# Bien — al menos deja un registro
try:
risky_operation()
except Exception as e:
print(f"Warning: {e}") # or logging.warning(...)

except: pass ignora "todos los errores". El programa no se detiene, pero no hay forma de saber qué salió mal. Más adelante, al depurar, será muy difícil encontrar la causa raíz.

Bloque except demasiado amplio

python
# Mal — también captura un error tipográfico (NameError)
try:
valeu = int(input("Enter number: ")) # typo: valeu
except Exception:
print("Entrada no válida") # ¿"Entrada no válida" aunque sea un NameError?
# Bien — capturar solo los errores previstos
try:
value = int(input("Enter number: "))
except ValueError:
print("Invalid input — please enter a number")

Resumen clave

SintaxisFunciónCuándo usarla
tryEnvolver código que puede generar erroresEntradas externas, archivos, redes, etc.
exceptCapturar un error específico y responderloCuando se requiere un manejo distinto según el tipo de error
elseEjecutar solo en caso de éxitoTareas adicionales cuando no hay errores
finallyEjecutar siempreTareas de limpieza (cerrar archivos, cerrar conexiones)
raiseGenerar un error directamenteEntradas inválidas, violación de reglas de negocio

El principio fundamental del manejo de excepciones es: capturar solo los errores esperados, hacerlo lo más específicamente posible y nunca ignorarlos. El pensamiento "envolverlo todo con try/except para estar seguro" es un error. Un manejo incorrecto de excepciones oculta los errores y dificulta la depuración incluso más que si no hubiera errores.


💬 Preguntas y comentarios

0 comentarios

Puedes publicar sin iniciar sesión. Los comentarios de invitados no pueden editarse ni eliminarse después.

0/2000

Cargando...