Introducción
En informática y programación, el manejo de excepciones es el proceso de responder a la ocurrencia de excepciones: condiciones anómalas o excepcionales que requieren un procesamiento especial. Python cuenta con muchas excepciones integradas que se activan cuando un programa encuentra un error. Además, muchas bibliotecas externas incluyen sus propias excepciones personalizadas que necesitarás gestionar.
En este laboratorio, aprenderás los fundamentos del manejo de excepciones en Python. Comenzarás con bloques básicos de try y except, pasarás a manejar múltiples excepciones, comprenderás el uso del bloque finally y, finalmente, crearás y gestionarás tus propias excepciones personalizadas.
Manejo básico de excepciones
En este paso, aprenderás los fundamentos del manejo de excepciones en Python utilizando bloques try y except.
Es un hecho matemático que no se puede dividir por cero. Si intentas hacer esto en Python, el intérprete lanzará un ZeroDivisionError integrado. Veamos esto en acción.
Nota: Si no estás familiarizado con el uso de WebIDE (similar a VS Code), por favor apréndelo primero en este laboratorio.
Primero, abre el archivo basic_handler.py desde el explorador de archivos a la izquierda y añade el siguiente código. Esto define una función de división simple.
def divide(dividend , divisor):
print(dividend / divisor)
divide(dividend=10, divisor=5)
Ahora, ejecuta el script desde la terminal:
python3 basic_handler.py
Verás el resultado correcto:
2.0
A continuación, veamos qué sucede cuando intentamos dividir por cero. Modifica la última línea en basic_handler.py para llamar a divide con un divisor de 0:
def divide(dividend , divisor):
print(dividend / divisor)
divide(dividend=10, divisor=0)
Ejecuta el script de nuevo:
python3 basic_handler.py
Esta vez, el programa se bloquea e imprime un rastreo (traceback), indicando un ZeroDivisionError:
Traceback (most recent call last):
File "/home/labex/project/basic_handler.py", line 4, in <module>
divide(dividend=10, divisor=0)
File "/home/labex/project/basic_handler.py", line 2, in divide
print(dividend / divisor)
ZeroDivisionError: division by zero
Para evitar que el programa se bloquee y, en su lugar, mostrar un mensaje amigable para el usuario, podemos "manejar" la excepción usando try y except. El código que podría causar un error se coloca dentro del bloque try, y el código que se ejecutará si ocurre ese error se coloca en el bloque except.
Actualiza el archivo basic_handler.py con el siguiente código para manejar el ZeroDivisionError de forma elegante:
## try-except: handle exceptions gracefully
def divide(dividend , divisor):
try: ## Try to execute this code
print(dividend / divisor)
except ZeroDivisionError: ## Catch specific exception type
print('You can not divide by 0')
divide(dividend=10, divisor=0)
Ahora, ejecuta el script una vez más:
python3 basic_handler.py
En lugar de bloquearse, el programa ahora imprime el mensaje útil que definiste y la ejecución finaliza normalmente:
You can not divide by 0
Manejo de múltiples excepciones usando un solo bloque
En este paso, descubrirás cómo manejar múltiples tipos de excepciones diferentes dentro de un solo bloque except. Esto es útil para simplificar tu código de manejo de errores cuando pueden ocurrir varios tipos de errores.
Puedes capturar una tupla de excepciones, como (ZeroDivisionError, TypeError), para manejarlas con la misma lógica.
Abre el archivo multiple_handler.py y añade el siguiente código. Esta función está diseñada para lanzar potencialmente un TypeError (al intentar concatenar una cadena y un entero) o un ZeroDivisionError.
## Handle multiple exceptions in one except block
def divide(dividend , divisor):
try:
if (dividend == 10):
var = 'str' + 1 ## This will raise TypeError
else:
print(dividend / divisor)
except (ZeroDivisionError, TypeError) as error: ## Catch multiple exception types
print(error) ## Print the error message
divide(dividend=20, divisor=5)
Primero, ejecutemos el código en un escenario donde no ocurre ninguna excepción. Ejecuta el script:
python3 multiple_handler.py
El resultado será el resultado de la división:
4.0
Ahora, activemos el TypeError. Modifica la última línea de multiple_handler.py para usar 10 como dividendo:
## ... (rest of the code) ...
divide(dividend=10, divisor=5)
Ejecuta el script de nuevo:
python3 multiple_handler.py
El bloque except captura el TypeError e imprime el mensaje de error asociado:
can only concatenate str (not "int") to str
Finalmente, activemos el ZeroDivisionError. Modifica la última línea de nuevo, esta vez intentando dividir por cero. Ten en cuenta que la condición TypeError (dividend == 10) no se cumple.
## ... (rest of the code) ...
divide(dividend=20, divisor=0)
Ejecuta el script:
python3 multiple_handler.py
El mismo bloque except ahora captura el ZeroDivisionError e imprime su mensaje:
division by zero
Para que la verificación sea exitosa, asegúrate de que la llamada final en tu script sea divide(dividend=10, divisor=5) para activar el TypeError.
El código Finally en el manejo de excepciones
En este paso, comprenderás el propósito y el uso del bloque finally. El código dentro de una cláusula finally siempre se ejecuta, independientemente de si se lanzó o manejó una excepción. Esto lo hace ideal para operaciones de limpieza, como cerrar un archivo o una conexión de red.
Veamos cómo funciona. Abre el archivo finally_handler.py y añade el siguiente código:
## finally block: always executes regardless of exceptions
def divide(dividend , divisor):
try:
print(dividend / divisor)
except ZeroDivisionError:
print('You can not divide by 0')
finally: ## Always executes, even if exception occurs
print('Execution finished')
divide(dividend=10, divisor=5)
Ejecuta el script desde tu terminal:
python3 finally_handler.py
En este caso, no ocurre ninguna excepción. El bloque try se completa con éxito y luego se ejecuta el bloque finally.
2.0
Execution finished
Ahora, introduzcamos un error. Modifica la última línea en finally_handler.py para dividir por cero:
## ... (rest of the code) ...
divide(dividend=10, divisor=0)
Ejecuta el script de nuevo:
python3 finally_handler.py
Esta vez, se lanza un ZeroDivisionError y es capturado por el bloque except. Aunque ocurrió una excepción, el bloque finally se ejecuta después de que el bloque except termina.
You can not divide by 0
Execution finished
Como puedes ver, el mensaje "Execution finished" se imprime en ambos escenarios, lo que demuestra que el bloque finally es un lugar confiable para el código que siempre debe ejecutarse.
Excepciones personalizadas
En este paso, aprenderás a crear tus propias excepciones personalizadas. Esta es una característica poderosa para hacer que tus aplicaciones sean más legibles y fáciles de mantener, ya que puedes crear tipos de error específicos que describan problemas únicos del dominio de tu programa.
Las excepciones personalizadas se definen creando una nueva clase que hereda de la clase base Exception de Python. Luego puedes activar esta excepción usando la palabra clave raise.
Abre el archivo custom_exception.py y añade el siguiente código para definir y lanzar una excepción personalizada simple:
## Custom exception: create by inheriting from Exception class
class MyCustomException(Exception):
pass
raise MyCustomException ## Raise the custom exception
Si ejecutas este script, se detendrá inmediatamente y mostrará un rastreo para tu nueva excepción:
python3 custom_exception.py
Traceback (most recent call last):
File "/home/labex/project/custom_exception.py", line 5, in <module>
raise MyCustomException ## Raise the custom exception
__main__.MyCustomException
También puedes proporcionar un mensaje descriptivo cuando lanzas una excepción personalizada. Modifica custom_exception.py para pasar una cadena a tu excepción:
class MyCustomException(Exception):
pass
raise MyCustomException('A custom message for my custom exception')
Ejecutar esto mostrará tu mensaje en el rastreo:
Traceback (most recent call last):
File "/home/labex/project/custom_exception.py", line 4, in <module>
raise MyCustomException('A custom message for my custom exception')
__main__.MyCustomException: A custom message for my custom exception
El manejo de una excepción personalizada se realiza de la misma manera que el manejo de una integrada: usando un bloque try...except. Actualiza custom_exception.py a su forma final, que lanza y maneja la excepción personalizada:
class MyCustomException(Exception):
pass
try:
raise MyCustomException('A custom message for my custom exception')
except MyCustomException:
print('My custom exception was raised')
Ahora, ejecuta el script por última vez:
python3 custom_exception.py
El programa ya no se bloquea. En su lugar, ejecuta el código en el bloque except e imprime tu mensaje de confirmación:
My custom exception was raised
Resumen
En este laboratorio, has aprendido las técnicas esenciales para manejar excepciones en Python. Comenzaste con los bloques básicos try y except para capturar errores específicos y evitar que los programas se bloqueen. Luego aprendiste cómo manejar eficientemente múltiples tipos de excepciones en un solo bloque except. También exploraste el bloque finally, que es crucial para el código de limpieza que siempre debe ejecutarse. Finalmente, adquiriste la capacidad de crear, lanzar y manejar tus propias excepciones personalizadas, lo que te permite construir una lógica de manejo de errores más robusta y descriptiva en tus aplicaciones.



