Introducción
En este laboratorio (lab), aprenderás cómo comprobar si se ha capturado una excepción en Python utilizando diferentes técnicas. El laboratorio se centra en el manejo de excepciones, un aspecto crucial para escribir código Python robusto y confiable.
El laboratorio te guiará a través de la comprensión del flujo de manejo de excepciones utilizando bloques try...except para manejar de forma elegante errores como ZeroDivisionError. Aprenderás cómo establecer una bandera (flag) dentro del bloque except para indicar que se ha capturado una excepción. Finalmente, el laboratorio presentará el concepto de utilizar gestores de contexto (context managers) para un manejo de excepciones más controlado.
Aprender el flujo de manejo de excepciones
En este paso, aprenderás sobre el manejo de excepciones en Python. El manejo de excepciones es una parte crucial para escribir código robusto y confiable. Te permite manejar de forma elegante los errores que pueden ocurrir durante la ejecución de tu programa, evitando que se bloquee y brindando una experiencia más amigable para el usuario.
Comencemos con un ejemplo sencillo. Imagina que quieres dividir dos números, pero el segundo número podría ser cero. Dividir por cero es una operación indefinida y generará un ZeroDivisionError en Python.
Abre el editor de VS Code en el entorno de LabEx.
Crea un nuevo archivo llamado
division.pyen el directorio~/project.touch ~/project/division.pyEdita el archivo
division.pyy agrega el siguiente código:## division.py numerator = 10 denominator = 0 result = numerator / denominator print(result)Ejecuta el script utilizando el comando
python:python ~/project/division.py
Verás un mensaje de error similar a este:
Traceback (most recent call last):
File "/home/labex/project/division.py", line 4, in <module>
result = numerator / denominator
ZeroDivisionError: division by zero
Este mensaje de error indica que se produjo un ZeroDivisionError porque intentamos dividir por cero. Sin manejo de excepciones, el programa se detiene abruptamente.
Ahora, usemos el manejo de excepciones para manejar este error de forma elegante.
Modifica el archivo
division.pypara incluir un bloquetry...except:## division.py numerator = 10 denominator = 0 try: result = numerator / denominator print(result) except ZeroDivisionError: print("Error: Cannot divide by zero.")En este código, el bloque
trycontiene el código que podría generar una excepción. Si se produce unZeroDivisionErrordentro del bloquetry, se ejecutará el código en el bloqueexcept.Vuelve a ejecutar el script:
python ~/project/division.py
Ahora, en lugar de bloquearse, el programa mostrará:
Error: Cannot divide by zero.
Esto demuestra la estructura básica del manejo de excepciones:
- El bloque
tryencierra el código que podría generar una excepción. - El bloque
exceptespecifica el tipo de excepción a capturar y el código a ejecutar si se produce esa excepción.
También puedes capturar múltiples tipos de excepciones utilizando múltiples bloques except:
## division.py
numerator = 10
denominator = "abc"
try:
result = numerator / int(denominator)
print(result)
except ZeroDivisionError:
print("Error: Cannot divide by zero.")
except ValueError:
print("Error: Invalid input. Please enter a number.")
En este ejemplo, hemos agregado un controlador de excepción ValueError. Si el denominator no se puede convertir a un entero (por ejemplo, si es una cadena como "abc"), se generará un ValueError y se ejecutará el bloque except correspondiente.
Ejecuta el script:
python ~/project/division.py
Salida:
Error: Invalid input. Please enter a number.
El manejo de excepciones te permite escribir programas más robustos y amigables para el usuario al anticipar y manejar posibles errores.
Establecer una bandera (flag) en el bloque except
En este paso, aprenderás cómo utilizar una bandera (flag) dentro de un bloque except para controlar el flujo de tu programa en función de si se produjo una excepción o no. Esta es una técnica útil cuando necesitas realizar diferentes acciones dependiendo del resultado del bloque try.
Basándonos en el ejemplo anterior, supongamos que quieres calcular el inverso de un número, pero solo si la división fue exitosa. Puedes utilizar una bandera para indicar si la división fue exitosa y luego calcular el inverso en consecuencia.
Abre el editor de VS Code en el entorno de LabEx.
Modifica el archivo
division.pyen el directorio~/projectpara incluir una bandera:## division.py numerator = 10 denominator = 2 success = True ## Inicializa la bandera en True try: result = numerator / denominator print("Result of division:", result) except ZeroDivisionError: print("Error: Cannot divide by zero.") success = False ## Establece la bandera en False si se produce un error except ValueError: print("Error: Invalid input. Please enter a number.") success = False ## Establece la bandera en False si se produce un error else: print("No exception occurred.") if success: try: reciprocal = 1 / result print("Reciprocal:", reciprocal) except ZeroDivisionError: print("Cannot calculate reciprocal of zero.") else: print("Reciprocal calculation skipped due to error.")En este código:
- Inicializamos una bandera llamada
successenTrueantes del bloquetry. - Si se produce un
ZeroDivisionErroroValueError, establecemos la banderasuccessenFalsedentro del bloqueexceptcorrespondiente. - Después del bloque
try...except, verificamos el valor de la banderasuccess. Si sigue siendoTrue, significa que no se produjo ninguna excepción y podemos calcular el inverso de forma segura. De lo contrario, omitimos el cálculo del inverso. - También agregamos un bloque
else, que se ejecutará si no se produce ninguna excepción en el bloquetry.
- Inicializamos una bandera llamada
Ejecuta el script con un denominador válido:
python ~/project/division.pySalida:
Result of division: 5.0 No exception occurred. Reciprocal: 0.2Ahora, cambia el
denominatora0y ejecuta el script nuevamente:## division.py numerator = 10 denominator = 0 ## Cambia el denominador a 0 success = True try: result = numerator / denominator print("Result of division:", result) except ZeroDivisionError: print("Error: Cannot divide by zero.") success = False except ValueError: print("Error: Invalid input. Please enter a number.") success = False else: print("No exception occurred.") if success: try: reciprocal = 1 / result print("Reciprocal:", reciprocal) except ZeroDivisionError: print("Cannot calculate reciprocal of zero.") else: print("Reciprocal calculation skipped due to error.")Ejecuta el script:
python ~/project/division.pySalida:
Error: Cannot divide by zero. Reciprocal calculation skipped due to error.
Esto demuestra cómo puedes utilizar una bandera en el bloque except para controlar el flujo de tu programa y realizar diferentes acciones en función de si se produjo una excepción o no.
Utilizar gestores de contexto (context managers) para control
En este paso, aprenderás cómo utilizar gestores de contexto (context managers) en Python para simplificar el manejo de excepciones y garantizar que los recursos se gestionen adecuadamente, incluso si se producen excepciones. Los gestores de contexto son especialmente útiles cuando se trabaja con archivos, conexiones de red y otros recursos que deben cerrarse o liberarse explícitamente.
Un gestor de contexto es un objeto que define los métodos __enter__ y __exit__. La declaración with se utiliza para ejecutar un bloque de código dentro del contexto de un gestor de contexto. El método __enter__ se llama cuando se ingresa al bloque with, y el método __exit__ se llama cuando se sale del bloque with, independientemente de si se produjo una excepción.
Comencemos con un ejemplo sencillo de lectura de un archivo utilizando un gestor de contexto.
Abre el editor de VS Code en el entorno de LabEx.
Crea un nuevo archivo llamado
file_handling.pyen el directorio~/project.touch ~/project/file_handling.pyEdita el archivo
file_handling.pyy agrega el siguiente código:## file_handling.py filename = "my_file.txt" try: with open(filename, "w") as f: f.write("Hello, LabEx!\n") f.write("This is a test file.\n") except IOError as e: print(f"An I/O error occurred: {e}") try: with open(filename, "r") as f: content = f.read() print("File content:") print(content) except FileNotFoundError: print(f"The file '{filename}' was not found.") except IOError as e: print(f"An I/O error occurred: {e}")En este código:
- Utilizamos la declaración
with open(filename, "w") as f:para abrir el archivomy_file.txten modo de escritura ("w"). La funciónopen()devuelve un objeto de archivo, que se asigna a la variablef. - La declaración
withgarantiza que el archivo se cierre automáticamente cuando se sale del bloque, incluso si se produce una excepción. - Escribimos dos líneas de texto en el archivo utilizando el método
f.write(). - Luego utilizamos la declaración
with open(filename, "r") as f:para abrir el mismo archivo en modo de lectura ("r"). - Leemos todo el contenido del archivo utilizando el método
f.read()y lo imprimimos en la consola. - Encerramos las operaciones de archivo en bloques
try...exceptpara manejar posibles excepcionesFileNotFoundErroryIOError.
- Utilizamos la declaración
Ejecuta el script:
python ~/project/file_handling.pySalida:
File content: Hello, LabEx! This is a test file.Si el archivo
my_file.txtno existe, el script lo creará y escribirá el contenido especificado. Si el archivo ya existe, su contenido se sobrescribirá. La declaraciónwithgarantiza que el archivo se cierre adecuadamente en cualquier caso.
Consideremos otro ejemplo en el que podría ocurrir una excepción durante el procesamiento del archivo:
## file_handling.py
filename = "my_file.txt"
try:
with open(filename, "r") as f:
for line in f:
## Simulate an error during processing
if "test" in line:
raise ValueError("Simulated error during processing")
print("Line:", line.strip())
except FileNotFoundError:
print(f"The file '{filename}' was not found.")
except ValueError as e:
print(f"A value error occurred: {e}")
except IOError as e:
print(f"An I/O error occurred: {e}")
En este ejemplo, simulamos un error al generar una excepción ValueError si la línea contiene la palabra "test". Incluso si se produce este error, la declaración with garantiza que el archivo se cierre adecuadamente.
Ejecuta el script:
python ~/project/file_handling.py
Salida:
Line: Hello, LabEx!
A value error occurred: Simulated error during processing
Los gestores de contexto proporcionan una forma limpia y confiable de gestionar recursos y manejar excepciones en Python. Garantizan que los recursos se liberen adecuadamente, incluso si se producen errores, lo que hace que tu código sea más robusto y fácil de mantener.
Resumen
En este laboratorio, comenzaste aprendiendo sobre el manejo de excepciones en Python, una técnica crucial para escribir código robusto. Comenzaste con un ejemplo sencillo de división que genera una excepción ZeroDivisionError cuando se divide por cero, lo que hace que el programa se detenga. Luego, implementaste un bloque try...except para manejar adecuadamente la excepción ZeroDivisionError, evitando que el programa se bloquee y mostrando en su lugar un mensaje de error informativo.



