Python utiliza un tipo de objeto especial denominado excepción para gestionar los errores que surgen durante la ejecución de un programa.
Cada vez que ocurre un error que hace que Python no sepa qué hacer a continuación, crea un objeto de excepción. Si se escribe código que maneja la excepción, el programa continuará ejecutándose. Por el contrario, si no se maneja la excepción, el programa se detendrá y mostrará un pequeño resumen de la excepción que se ha producido.
Las excepciones se pueden manejan a través de las sentencias try y except.
print(var)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[1], line 1
----> 1 print(var)
NameError: name 'var' is not defined
2. Errores de sintaxis vs Excepciones
A pesar de que en muchas ocasiones estos dos términos se utilizan de manera indistinta cuando hablamos de Python, debemos tener cuidado porque son cosas diferentes.
Los errores de sintaxis se producen cuando escribimos una sentencia de código en Python que no es sintácticamente válida. El intérprete de Python indica estos error con el término SyntaxError y nos señala con el carácter ^ donde se encuentra el error.
print("Hola mundo)
Cell In[2], line 1
print("Hola mundo)
^
SyntaxError: unterminated string literal (detected at line 1)
Este tipo de errores no se pueden controlar y no se corresponden con excepciones dentro del lenguaje
Por otro lado, las excepciones se corresponden con errores que se producen en sentencias de código en Python que son sintácticamente correctas. Esto tipo de errores no son fatales para el programa y pueden ser gestionados o ignorados.
print(var)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[3], line 1
----> 1 print(var)
NameError: name 'var' is not defined
50/0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
Cell In[4], line 1
----> 1 50/0
ZeroDivisionError: division by zero
'2' + 2
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[5], line 1
----> 1 '2' + 2
TypeError: can only concatenate str (not "int") to str
3. Gestión de excepciones: Sentencias try y except
Las sentencias try y except en Python pueden utilizarse para capturar y manejar excepciones. Python ejecuta el código que sigue a la sentencia try como una parte "normal" del programa. El código que sigue a la sentencia except se ejecutará si se produce cualquier excepción en la cláusula try precedente.
La sintaxis que se utiliza para definir este tipo de comportamiento es la siguiente:
try:
<sentencia(s)>
except <excepción>:
<sentencias(s) si excepción>
print(var)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[6], line 1
----> 1 print(var)
NameError: name 'var' is not defined
try:
print(var)
except NameError:
var = "Hola mundo"
print(var)
Hola mundo
Debemos tener en cuenta que el las sentencias de código que se encuentren en el cuerpo de la sentencia try y a continuación de la sentencia que emite la excepción, no se ejecutarán
print("...SNIP...")
try:
print("Código antes de la excepción")
10 + '3'
print("Código despues de la excepción")
except TypeError:
print("[!] No se puede sumar un número entero y un string")
print("...SNIP...")
...SNIP...
Código antes de la excepción
[!] No se puede sumar un número entero y un string
...SNIP...
También podemos utilizar la sentencia except sin indicarle el nombre de ninguna excepción, en estos casos capturará todas las excepciones que se produzcan en el código que se encuentra en el cuerpo de la sentencia try
print("...SNIP...")
try:
10 + '3'
except:
print("[!] No se puede sumar un número entero y un string")
print("...SNIP...")
...SNIP...
[!] No se puede sumar un número entero y un string
...SNIP...
Adicionalmente a la sintaxis anterior, podemos capturar varias excepciones de manera simultánea utilizando varias cláusulas except
try:
print(50/0) # Error de ZeroDivisionError
except NameError:
print("[+] Gestionando excepcion NameError")
except TypeError:
print("[+] Gestionando excepcion TypeError")
except ZeroDivisionError:
print("[+] No puedes dividir un número por 0")
[+] No puedes dividir un número por 0
Por último, podemos asignar el objeto excepción capturado a una variable y utilizarlos para mostrar más información al respecto.
try:
print(variable)
except NameError as error:
print("[*] Objeto de tipo:", type(error))
print("[!] La excepción consiste en:", error)
[*] Objeto de tipo: <class 'NameError'>
[!] La excepción consiste en: name 'variable' is not defined
4. Lanzando excepciones personalizadas
Además de las sentencias anteriores que podemos utilizar para controlar excepciones, Python nos proporciona la sentencia raise con la que podemos emitir nuestras propias excepciones. Para ello, debemos utilizar la clase por defecto de Python Exception
help(Exception)
colores_permitidos = ("azul", "verde", "amarillo", "rojo")
color = "morado"
if color not in colores_permitidos:
raise Exception("[!] El color {} no está en la lista de colores permitidos".format(color))
# Al ejecutar este código nos devuelve una Exception personalizada
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
Cell In[21], line 6
3 color = "morado"
5 if color not in colores_permitidos:
----> 6 raise Exception("[!] El color {} no está en la lista de colores permitidos".format(color))
Exception: [!] El color morado no está en la lista de colores permitidos
5. Excepción AssertionError
Como complemento a todas las sentencias anteriores, Python nos proporciona una sentencia adicional que nos permite verificar en un punto determinado de nuestro programa que todo esta funcionando adecuadamente, esta sentencia es assert.
passwd = input("Introduce una contraseña de más de 8 digitos:")
assert len(passwd) > 8, "[!] La contraseña es menor a 8 digitos"
Introduce una contraseña de más de 8 digitos: 1234
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
Cell In[22], line 3
1 passwd = input("Introduce una contraseña de más de 8 digitos:")
----> 3 assert len(passwd) > 8, "[!] La contraseña es menor a 8 digitos"
AssertionError: [!] La contraseña es menor a 8 digitos
6. Cláusula else en excepciones
Curiosamente, Python nos proporciona un mecanismo por el cual utilizando la sentencia else, se puede indicar a un programa que ejecute un determinado bloque de código sólo en ausencia de excepciones.
try:
print(variable_no_definida)
except NameError:
print("[!] La variable no está definida, se define con la cadena 'Hola mundo'")
variable_no_definida = 'Hola mundo'
else:
print("[+] La variable ya estaba definida con el valor:", variable_no_definida)
Hola mundo
[+] La variable ya estaba definida con el valor: Hola mundo
7. Sentencia finally
Python nos proporciona una última sentencia que podemos utilizar para realizar una "limpieza" después de la ejecución de nuestro código al gestionar una excepción. Esta sentencia se denomina finally y el código que se localice en su cuerpo, se ejecutará siempre, independientemente de si se produce o no la excepción.
try:
print(variable3)
except NameError:
print("[!] La variable no está definida, se define con la cadena 'Hola mundo'")
variable3 = 'Hola mundo'
else:
print("[+] La variable ya estaba definida con el valor:", variable3)
Hola mundo
[+] La variable ya estaba definida con el valor: Hola mundo
try:
print(variable3)
except NameError:
print("[!] La variable no está definida, se define con la cadena 'Hola mundo'")
variable3 = 'Hola mundo'
else:
print("[+] La variable ya estaba definida con el valor:", variable3)
finally:
del variable3 # Siempre se ejecutará esta línea de código
[!] La variable no está definida, se define con la cadena 'Hola mundo'