6.3 Excepciones
Una excepción es el bloque de código que se lanza cuando se produce un error en la ejecución de un programa Python.
De hecho ya hemos visto algunas de estas excepciones: accesos fuera de rango a listas o tuplas, accesos a claves inexistentes en diccionarios, etc. Cuando ejecutamos código que podría fallar bajo ciertas circunstancias, necesitamos también manejar, de manera adecuada, las excepciones que se generan.
Si una excepción ocurre en algún lugar de nuestro programa y no es capturada en ese punto, va subiendo (burbujeando) hasta que es capturada en alguna función que ha hecho la llamada. Si en toda la «pila» de llamadas no existe un control de la excepción, Python muestra un mensaje de error con información adicional:
Para manejar (capturar) las excepciones podemos usar un bloque de código con las palabras reservadas try and except:
Aquel código que se encuentre dentro del bloque try se ejecutará normalmente siempre y cuando no haya un error. Si se produce una excepción, ésta será capturada por el bloque except, ejecutándose el código que contiene.
Consejo: No es una buena práctica usar un bloque except sin indicar el tipo de excepción que estamos gestionando, no sólo porque puedan existir varias excepciones que capturar sino porque, como dice el Zen de Python: «explícito» es mejor que «implícito».
Especificando excepciones
En el siguiente ejemplo mejoraremos el código anterior, capturando distintos tipos de excepciones:
- TypeError por si los operandos no permiten la división.
- ZeroDivisionError por si el denominador es cero.
- Exception para cualquier otro error que se pueda producir.
Veamos su implementación:
Cubriendo más casos
Python proporciona la cláusula else para saber que todo ha ido bien y que no se ha lanzado ninguna excepción. Esto es relevante a la hora de manejar los errores.
De igual modo, tenemos a nuestra disposición la cláusula finally que se ejecuta siempre, independientemente de si ha habido o no ha habido error.
Veamos un ejemplo de ambos:
Ejercicio
Sabiendo que ValueError es la excepción que se lanza cuando no podemos convertir una cadena de texto en su valor numérico, escriba una función get_int() que lea un valor entero del usuario y lo devuelva, iterando mientras el valor no sea correcto.
Ejecución a modo de ejemplo:
Trate de implementar tanto la versión recursiva como la versión iterativa.
Nivel avanzado
Python ofrece una gran cantidad de excepciones predefinidas. Hasta ahora hemos visto cómo gestionar y manejar este tipo de excepciones. Pero hay ocasiones en las que nos puede interesar crear nuestras propias excepciones. Para ello tendremos que crear una clase heredando de Exception, la clase base para todas las excepciones.
Veamos un ejemplo en el que creamos una excepción propia controlando que el valor sea un número entero:
Hemos usado la sentencia raise para «elevar» esta excepción, que podría ser controlada en un nivel superior mediante un bloque try – except.
Mensaje personalizado
Podemos personalizar la excepción añadiendo un mensaje más informativo. Siguiendo el ejemplo anterior, veamos cómo introducimos esta información:
Podemos ir un paso más allá e incorporar en el mensaje el propio valor que está generando el error:
Si hablamos de control de errores hay que citar una sentencia en Python denominada assert. Esta sentencia nos permite comprobar si se están cumpliendo las «expectativas» de nuestro programa, y en caso contrario, lanza una excepción informativa.
Su sintaxis es muy simple. Unicamente tendremos que indicar una expresión de comparación después de la sentencia:
En el caso de que la condición se cumpla, no sucede nada: el programa continúa con su flujo normal. Esto es indicativo de que las expectativas que teníamos se han satisfecho.
Sin embargo, si la condición que fijamos no se cumpla, la aserción devuelve un error AssertionError y el programa interrupme su ejecución:
Podemos observar que la excepción que se lanza no contiene ningún mensaje informativo. Es posible personalizar este mensaje añadiendo un segundo elemento en la tupia de la aserción:
AMPLIAR CONOCIMIENTOS
- Python Exceptions: An introduction
- Python KeyError Exceptions and How to Handle Them
- Understanding the Python Traceback