Domina el manejo de excepciones en Python (try-except)
Para ejecutar Python desde el símbolo del sistema o PowerShell en tu PC, necesitas descargar e instalar Python.
Si aún no lo has hecho, consulta el artículo Instalación de Python y configuración del entorno de desarrollo para instalar Python.
Cuando escribes programas, es inevitable encontrar errores inesperados. Las causas de los errores son variadas: entradas incorrectas del usuario, archivos que no existen, problemas de red, etc. Para esas situaciones, el "manejo de excepciones" es el mecanismo que evita que tu programa se bloquee repentinamente y te permite responder de manera inteligente.
En este artículo, explicaremos desde lo básico hasta las aplicaciones avanzadas del manejo de excepciones usando la sentencia try-except de Python, con ejemplos de código que puedes copiar, pegar y ejecutar de inmediato. ¡Vamos a dominar cómo crear programas robustos y a prueba de errores experimentando con código que "funciona"!_
¡Empecemos por lo básico! La sintaxis de try-except
La forma más fundamental de manejo de excepciones es la sentencia try-except. Como su nombre indica, crea un flujo de "try (intenta esto), y si ocurre una excepción (error), except (captúrala y manéjala)".
La sintaxis es muy simple:
- Dentro del bloque
try, escribes el código que podría generar un error. - Dentro del bloque
except, escribes el código que quieres que se ejecute cuando ocurra un error.
Una imagen vale más que mil palabras. Veamos el famoso "error de división por cero" (ZeroDivisionError) como ejemplo. En el siguiente código, intentamos dividir 10 entre 0. Normalmente, esto detendría el programa con un error, pero con try-except, lo capturamos adecuadamente.
<!-- Código Python -->
try:
# Código que podría generar un error
result = 10 / 0
print(f"Resultado del cálculo: {result}")
except ZeroDivisionError:
# Acción a tomar si ocurre un ZeroDivisionError
print("¡Uy! No puedes dividir por cero.")
print("El programa finalizó correctamente.")
¡Apuntando a excepciones específicas! Múltiples except
En un programa, pueden ocurrir varios tipos de errores. Por ejemplo, en la entrada del usuario, "se esperaba un número pero se introdujo texto" (ValueError), o en operaciones con archivos, "no se encuentra el archivo especificado" (FileNotFoundError).
Al especificar el tipo de error (la clase de la excepción) después de la sentencia except, puedes capturar solo errores específicos y realizar el tratamiento adecuado para cada uno.
Además, puedes encadenar múltiples bloques except para escribir manejadores diferentes según el tipo de error. El siguiente ejemplo intenta convertir una cadena de texto a un entero.
<!-- Código Python -->
user_input = "hola" # Texto en lugar de un número
try:
num = int(user_input)
print(f"Número introducido: {num}")
except ValueError:
print("¡Por favor, introduce un número! El texto no se puede convertir a número.")
except TypeError:
print("¡El tipo de dato es incorrecto! No se puede convertir a número.")
print("Continuando con el proceso...")
A menudo querrás conocer la información detallada (mensaje de error) del error que ha ocurrido. En ese caso, puedes usar as para almacenar el objeto de la excepción en una variable. Generalmente, se usa el nombre de variable e (inicial de error o exception).
<!-- Código Python -->
try:
# Intentar abrir un archivo que no existe
with open("archivo_inexistente.txt", "r") as f:
content = f.read()
except FileNotFoundError as e:
# Mostrar la información detallada del error
print(f"No se encontró el archivo.")
print(f"Detalles del error: {e}")
Uso avanzado: Dominando else y finally
El try-except tiene dos compañeros poderosos: else y finally. Combinarlos permite un control aún más detallado.
- Bloque else: Se ejecuta solo si no ocurrió ninguna excepción en el bloque
try. Es útil para separar claramente el código de éxito del código de manejo de errores. - Bloque finally: Se ejecuta siempre al final, sin importar si ocurrió una excepción o no. Es ideal para escribir código de limpieza, como cerrar archivos o conexiones de red.
Veamos un código que utiliza todos estos elementos.
<!-- Código Python -->
file_path = "mis_datos.txt"
data_to_write = "Estos son datos de prueba."
try:
print(f"Escribiendo datos en '{file_path}'...")
f = open(file_path, "w", encoding="utf-8")
# Para provocar un error a propósito, descomenta la siguiente línea
# f.write(12345) # Intentar escribir algo que no es texto causa un TypeError
f.write(data_to_write)
print("Se ha intentado escribir.")
except TypeError as e:
print(f"¡Error! Los datos a escribir deben ser una cadena de texto.")
print(f"Detalles del error: {e}")
except Exception as e:
# Capturar cualquier otro error inesperado
print(f"Ha ocurrido un error inesperado.")
print(f"Detalles del error: {e}")
else:
# Se ejecuta si no ocurrió ninguna excepción en el bloque try
print("¡La escritura en el archivo se ha completado con éxito!")
finally:
# Se ejecuta siempre, haya o no excepción
if 'f' in locals() and not f.closed:
f.close()
print("El archivo ha sido cerrado.")
else:
print("El archivo no estaba abierto o ya se había cerrado.")
print("--- Proceso completado ---")
¡En práctica! Un ejemplo de código completo para copiar y pegar
Ahora, usemos todo lo que hemos aprendido para crear un programa más práctico. Este código le pide al usuario su edad y sigue preguntando hasta que se introduce un número válido. Luego, guarda la edad introducida en un archivo. Los posibles errores que puedan surgir en el proceso se manejan con try-except.
Copia todo el código de abajo, guárdalo en un archivo llamado age_logger.py y ejecútalo en tu terminal con python age_logger.py. ¡Prueba a introducir texto a propósito para ver cómo funciona el manejo de errores!
<!-- Script completo de Python: age_logger.py -->
import datetime
def record_age():
"""
Función que pide la edad al usuario y la guarda en un archivo.
Maneja la validación de la entrada y los errores de E/S de archivos.
"""
while True:
try:
# Recibir la entrada del usuario
age_str = input("Por favor, introduce tu edad con números: ")
# Convertir la cadena de texto a un entero
age = int(age_str)
# Comprobar si hay valores negativos o edades poco realistas
if age < 0 or age > 130:
# Lanzar un error personalizado (raise)
raise ValueError("La edad debe estar entre 0 y 130.")
# Si se introduce una edad válida, salir del bucle
break
except ValueError as e:
# Capturar el error de la conversión int() o el que hemos lanzado con raise
print(f"Error: {e}")
print("Por favor, inténtalo de nuevo con un número válido.\n")
# Guardar en el archivo
try:
# Usar "with" cierra el archivo automáticamente, por lo que no se necesita finally para close()
with open("age_log.txt", "a", encoding="utf-8") as f:
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
f.write(f"[{timestamp}] Edad registrada: {age} años\n")
print(f"Tu edad, '{age} años', ha sido guardada en 'age_log.txt'.")
except IOError as e:
# Capturar errores como la falta de permisos de escritura
print("Error fatal: No se pudo escribir en el archivo.")
print(f"Detalles del error: {e}")
if __name__ == "__main__":
record_age()
print("Gracias por usar el programa.")
Puntos a tener en cuenta: Capturar excepciones de forma amplia
El manejo de excepciones es útil, pero si se usa incorrectamente, puede hacer que sea más difícil encontrar problemas en tu programa. Un punto de especial cuidado es capturar excepciones de un ámbito demasiado amplio.
No recomendado: except sin especificar
La peor práctica es un except: "desnudo" que no especifica una clase de excepción. Esto captura todos los errores sin discriminación. Esto incluye SystemExit, que se usa para terminar el programa, e incluso KeyboardInterrupt cuando se presiona Ctrl+C. Podrías terminar en una situación en la que ni siquiera puedes detener tu programa cuando quieres.
Usar con precaución: except Exception
except Exception as e: es mejor que un except: desnudo, pero aun así captura la mayoría de los errores comunes. Durante el desarrollo, a menudo quieres que los errores ocurran para encontrar bugs inesperados. Si lo capturas todo, los bugs que deberían ser corregidos pueden quedar ocultos.
La mejor práctica es "especificar y capturar solo aquellas excepciones que puedes predecir y manejar adecuadamente".
Resumen y próximos pasos
En este artículo, hemos aprendido sobre la sentencia try-except de Python para el manejo de excepciones. Repasemos los puntos clave:
- Puedes evitar que el programa se bloquee por errores con
try-except. - Con
except ClaseDeExcepcion as e, puedes capturar errores específicos y obtener información detallada. - Usa
elsepara el código que se ejecuta en caso de éxito yfinallypara las operaciones de limpieza. - El truco está en limitar la captura de excepciones a casos específicos y manejables, en lugar de ser demasiado general.
Al dominar el manejo de excepciones, puedes construir aplicaciones robustas que sean amigables para el usuario y fáciles de mantener para los desarrolladores. ¡No dudes en introducir try-except en tu propio código!
Como siguiente paso, ¿por qué no aprender sobre un concepto importante para modularizar tu programa y aumentar su reutilización?
>> Siguiente artículo: Introducción a las Clases y Programación Orientada a Objetos en Python