A lo largo de las entradas nos hemos topado con algunos errores que de momento ha sido sencillo resolver. Vamos a hablar sobre el manejo de errores en Python para poder incluir este tipo de mecanismo en nuestros programas ya que es una herramienta muy útil.
Cuando Python encuentra un error en un programa, detiene la ejecución para indicar el error que detectó. Vamos a aprender cómo manejar los errores cuando aparezcan sin que sea necesario detener el programa.
Es posible toparnos con dos tipos de errores:
- Errores de sintaxis
- Excepciones
Vamos a ver de qué se trata cada uno.
Errores de sintaxis
Cuando tenemos algún detalle al escribir nuestro código, Python nos lo indica regresando un error de sintaxis. Generalmente al regresar este tipo de error se muestra la línea de código en la que se presenta el error y una flecha indicando el sitio en el que ya no se pudo continuar.
Tuvimos un error de este tipo en la entrada Variables cuando intentamos usar una palabra reservada como variable. Veámoslo de nuevo, el código es el siguiente:
global = "Hola mundo"
>>> global = «Hola mundo»
File «<stdin>», line 1
global = «Hola mundo»
^
SyntaxError: invalid syntax
>>>
Al regresar el error, Python incluyo un indicador debajo del signo igual para indicar que hasta ahí llego cuando detectó el error. La ultima línea que regresa Python es muy útil porque indica de qué se trata el error, en este caso pone «SyntaxError» después incluye una descripción de lo que encontró: «invalid syntax».
Excepciones
Python cuenta con una amplia lista de excepciones predefinidas. Al igual que en el Error de Sintaxis, cuando Python encuentra una excepción aparece el nombre y una pequeña descripción en la ultima línea del mensaje que regresa.
Justo cuando iniciábamos esta serie nos topamos con una excepción, tomemos el código de la entrada ¡Quiero comenzar!
Print("10 + 5 =", 10 + 5)
>>> Print(«10 + 5 =», 10 + 5)
Traceback (most recent call last):
File «<stdin>», line 1, in <module>
NameError: name ‘Print’ is not defined
Con el código anterior obtuvimos una excepción de tipo «NameError» y la descripción nos indica que el nombre Print no está definido.
¿Qué hago con los errores?
En esta sección vamos a utilizar el siguiente código para ejemplificar el manejo de errores en Python . Las siguientes líneas generan una excepción de tipo «ZeroDivisionError» al intentar dividir entre cero.
for i in range(2,-2,-1):
div = 10 / i
print(i, div)
>>> for i in range(2,-2,-1):
… div = 10 / i
… print(i, div)
…
2 5.0
1 10.0
Traceback (most recent call last):
File «<stdin>», line 2, in
ZeroDivisionError: division by zero
Para gestionar los errores debemos incluir try y except en nuestro código, la estructura general es la siguiente:
try:
instrucción
except excepción:
instrucción
Al incluir esta estructura, Python va a intentar correr las instrucciones que se encuentran dentro del bloque try, si no se presenta una excepción continua con la ejecución de las instrucciones que se encuentran después del bloque except si las hubiera. Pero si al ejecutar las instrucciones del bloque try encuentra una excepción entonces Python se pasa al bloque except. Vamos a modificar el código con el que iniciamos para ver cómo funciona..
for i in range(2,-2,-1):
try:
div = 10 / i
print(i, div)
except ZeroDivisionError:
print("Llegue a cero")
>>> for i in range(2,-2,-1):
… try:
… div = 10 / i
… print(i, div)
… except ZeroDivisionError:
… print(«Llegue a cero»)
…
2 5.0
1 10.0
Llegue a cero
-1 -10.0
En el código inicial el programa se detuvo en cuanto detecto la excepción. Con la modificación para incluir try y except, la ejecución no se detuvo, llego hasta el final pero si nos indicó el momento en el que se presentó el error. En la salida veras que en lugar de detener la ejecución al detectar la excepción, se ejecuto la instrucción que esta dentro del except. Vamos a hacer otro cambio al codigo.
for i in range(2,-2,-1):
try:
div = 10 / i
print(i, div)
except NameError:
print("Llegue a cero")
>>> for i in range(2,-2,-1):
… try:
… div = 10 / i
… print(i, div)
… except ZeroDivisionError:
… print(«Llegue a cero»)
…
2 5.0
1 10.0
Traceback (most recent call last):
File «<stdin>», line 3, in
ZeroDivisionError: division by zero
¿Qué paso aquí? Para que se haga un adecuado manejo de errores debemos indicar en el código el nombre de la excepción que pudiera ocurrir. Al cambiar «ZeroDivisionError» por «NameError» dejamos sin alternativa a Python al momento de encontrarse con la excepción que se genera al dividir entre cero. Por ello volvimos a tener un error aun cuando incluimos try y except.
Es posible incluir varias secciones de except de forma que tengamos mas alternativas cubiertas. Podríamos modificar el código de la siguiente forma:
for i in range(2,-2,-1):
try:
div = 10 / i
print(i, div)
except NameError:
print("Nombre erroneo")
except ZeroDivisionError:
print("Llegue a cero")
>>> for i in range(2,-2,-1):
… try:
… div = 10 / i
… print(i, div)
… except NameError:
… print(«Nombre erroneo»)
… except ZeroDivisionError:
… print(«Llegue a cero»)
…
2 5.0
1 10.0
Llegue a cero
-1 -10.0
Ahora nuestro código esta cubierto en caso de que se pudieran presentar alguna de las dos excepciones. Aunque tengamos varios bloques de except definidos, solo se ejecutaría un except al encontrarse el error. En un solo bloque de except se pueden incluir varias excepciones. Hagamos mas cambios.
for i in range(2,-2,-1):
try:
div = 10 / i
print(i, div)
except (NameError, ZeroDivisionError):
print("Hay un problema")
>>> for i in range(2,-2,-1):
… try:
… div = 10 / i
… print(i, div)
… except (NameError, ZeroDivisionError):
… print(«Hay un problema»)
…
2 5.0
1 10.0
Hay un problema
-1 -10.0
Conocer el tipo de error que se nos puede presentar nos permite tener alternativas para no detener la ejecución de nuestros programas aun cuando tengamos errores.
Cuéntame, ¿qué te pareció el manejo de errores en Python?
En la siguiente entrada hablaremos sobre más tipos de datos que podemos utilizar en nuestros programas.