TutorialesManejo de Excepciones en Python: Try, Except y Errores

Manejo de Excepciones en Python: Try, Except y Errores

Imagina que estás conduciendo un coche flamante y, de repente, una pequeña piedra salta de la carretera y golpea el parabrisas. Si tu coche no tuviera cristales de seguridad, el parabrisas entero estallaría en pedazos, obligándote a detener el viaje de inmediato. Afortunadamente, los coches están diseñados para amortiguar estos impactos sin que el motor deje de funcionar.

En el desarrollo de software ocurre exactamente lo mismo. Un usuario puede introducir una letra en lugar de un número, un servidor web puede caerse por unos segundos o un archivo que necesitas abrir puede haber sido borrado. Si tu programa no sabe cómo gestionar estos imprevistos, se cerrará de golpe (haciendo un «crash») y arruinará la experiencia del usuario.

En este tutorial vas a dominar el manejo de excepciones en Python de forma práctica. Aprenderás a utilizar los bloques try, except, else y finally, descubrirás por qué capturar errores genéricos es un error grave y aprenderás a escribir aplicaciones verdaderamente robustas y profesionales.

Echa un vistazo al bloque completo de control de errores para ver lo limpio que queda tu código:

try:
    # Código "arriesgado" que puede fallar
    edad = int(input("Introduce tu edad: "))
    resultado = 100 / edad
except ValueError:
    # Se ejecuta si el usuario no mete un número
    print("Error: Debes introducir un número entero válido.")
except ZeroDivisionError:
    # Se ejecuta si el usuario introduce un cero
    print("Error: La edad no puede ser cero.")
else:
    # Se ejecuta solo si todo ha ido bien
    print(f"Tienes {edad} años. ¡Perfecto!")
finally:
    # Se ejecuta SIEMPRE (limpieza)
    print("Fin de la validación.")

1. ¿Qué son las Excepciones en Python?

Es fundamental distinguir entre dos tipos de problemas muy diferentes que pueden detener tu código:

  • Errores de Sintaxis (SyntaxError): Ocurren cuando escribes mal el código (por ejemplo, te olvidas de los dos puntos : al definir una función o abres un paréntesis y no lo cierras). El intérprete de Python detecta esto antes de arrancar el programa y ni siquiera te dejará ejecutarlo.
  • Excepciones (Exceptions): Son errores que ocurren durante la ejecución del programa (en tiempo de ejecución). El código está bien escrito sintácticamente, pero ocurre un evento imprevisto (como dividir por cero o intentar abrir un archivo que no existe en el disco).

El objetivo del manejo de excepciones en Python es capturar estos fallos en tiempo de ejecución para darles una respuesta elegante en lugar de permitir que la aplicación se cierre abruptamente.


2. La Estructura Básica: try y except

La forma más sencilla de interceptar un error es envolver el código sospechoso en un bloque try y definir qué hacer si falla en el bloque except:

# Intentar abrir un archivo inexistente
try:
    with open("datos_secretos.txt", "r") as archivo:
        contenido = archivo.read()
except FileNotFoundError:
    # Captura únicamente el error de archivo no encontrado
    print("Aviso: El archivo no existe. Creando uno por defecto...")

⚠️ La Trampa Peligrosa: El «Catch-All» (except genérico)

Muchos desarrolladores novatos cometen la imprudencia de escribir un bloque except: vacío o capturar la clase base Exception para evitarse escribir el nombre del error. Esto es una pésima práctica:

# CÓDIGO PELIGROSO (Anti-patrón)
try:
    resultado = 10 / divisor
except:
    print("Ha ocurrido un error")  # ¿Qué error? ¡Ni idea!

¿Por qué es peligroso? Un `except` genérico capturará absolutamente cualquier error, incluidos fallos de escritura de variables como un NameError (por ejemplo, si has escrito mal el nombre de una variable) o incluso la señal de teclado para cerrar el terminal (KeyboardInterrupt). Ocultarás bugs reales en tu código haciéndolos imposibles de depurar.

Como buena práctica profesional: captura siempre excepciones específicas de las que conozcas su origen.


3. El Poder de los Bloques else y finally

Para lograr un control de flujo limpio y robusto, Python nos ofrece dos bloques adicionales muy potentes:

El Bloque else: Mantén tu try enano

El código dentro del bloque else se ejecutará única y exclusivamente si no se ha lanzado ninguna excepción dentro del bloque try.

Esto te permite seguir una regla de oro del desarrollo de software: mantener el bloque try lo más pequeño posible. Solo debes meter dentro del try la línea exacta que tiene riesgo de fallar (por ejemplo, la conexión a una base de datos), dejando el resto de la lógica en el bloque else:

try:
    # Solo metemos la línea de riesgo
    conexion = conectar_servidor()
except ConnectionError:
    print("Error: No se pudo establecer la conexión.")
else:
    # Esta parte solo corre si la conexión fue un éxito total
    print("Conexión establecida.")
    enviar_datos(conexion)

El Bloque finally: El Guardián de la Limpieza

El bloque finally es incondicional: se ejecutará siempre, tanto si el código del try funciona a la perfección como si salta un error catastrófico y el programa se va a interrumpir.

Es la herramienta idónea para realizar operaciones de limpieza críticas, como cerrar un archivo abierto, liberar memoria o cerrar conexiones de bases de datos para evitar fugas de recursos:

try:
    archivo = open("registro.log", "w")
    archivo.write("Acceso de usuario")
    # Si esta línea da error, el programa saltaría...
    resultado = 10 / 0
except ZeroDivisionError:
    print("Error matemático.")
finally:
    # ...pero antes de romper nada, finally garantiza que el archivo se cierra
    archivo.close()
    print("Archivo cerrado de forma segura.")

4. Cómo Lanzar Excepciones Manualmente con raise

A medida que escribes tus propias funciones en Python, llegará un punto en el que necesitarás forzar el lanzamiento de un error si los datos que recibe tu función no son válidos.

Para lanzar un error de forma voluntaria en tu código, utilizamos la palabra reservada raise acompañada del tipo de excepción y un mensaje explicativo:

def registrar_edad(edad):
    if edad < 0:
        # Lanzamos un error de valor inválido de forma manual
        raise ValueError("La edad no puede ser un número negativo.")
    return f"Edad registrada: {edad}"

try:
    registrar_edad(-5)
except ValueError as error:
    # Capturamos el error y accedemos al mensaje descriptivo
    print(f"Error detectado: {error}")  # Salida: Error detectado: La edad no puede ser un número negativo.

5. Resumen de Flujo: ¿Qué bloque se ejecuta y cuándo?

Para tener una referencia rápida de la anatomía del control de errores en Python, repasa la siguiente tabla:

Bloque¿Cuándo se ejecuta?¿Es obligatorio?
trySiempre al iniciar la estructura de control. Contiene el código sensible.
exceptSolo si ocurre un error o excepción específica dentro del try.Sí (al menos uno, o un bloque finally)
elseSolo si el bloque try finalizó con éxito absoluto sin ningún error.No (opcional)
finallySiempre. Haya habido errores, éxitos o interrupciones.No (opcional)

6. Errores Comunes al Manejar Excepciones

❌ Error de Orden en Múltiples Excepts

Si capturas una excepción muy general (como Exception) antes de capturar una específica (como ZeroDivisionError), la específica nunca llegará a ejecutarse porque la general se la quedará antes:

# CÓDIGO CON ERROR
try:
    resultado = 10 / 0
except Exception:
    print("Capturado por general")
except ZeroDivisionError:
    print("Este bloque nunca se ejecutará")  # Advertencia del editor

Solución: Escribe siempre las excepciones más específicas arriba del todo, y deja las más generales (si es que necesitas usarlas) en la parte inferior de la estructura.


Conclusión y Fin de Fundamentos

El control y manejo de excepciones en Python es la herramienta clave para dar el salto de programador novato a desarrollador profesional. Te permite crear aplicaciones sólidas que no se rompen ante imprevistos, gestionando de forma elegante desde las interacciones con diccionarios en Python hasta accesos a bases de datos y flujos de red complejos.

Con este tutorial cerramos el bloque fundamental de nuestro roadmap de aprendizaje. ¡Enhorabuena por completar esta etapa de cimientos sólidos! En la próxima entrega daremos el salto a la programación avanzada estructurando código a gran escala. ¡Nos vemos en el próximo bloque de Todo Python!

Artículo anterior
Artículo siguiente