Tema 15. Errores y Excepciones

Explicación de como controlar los errores y excepciones derivados del uso de nuestros scripts en Python 3.

A lo largo de este tema vamos a aprender sobre los diferentes tipos de errores y excepciones que existen en Python. Tanto los errores como las excepciones saltan cuando el intérprete de Python encuentra algún error.

Es completamente normal cometer ciertos errores mientras se escribe un programa. Estos fallos conducen a errores cuando tratamos de ejecutar dicho programa. La ejecución termina al instante de encontrar alguno de esos fallos, que pueden ser de dos tipos:

  1. Error de sintaxis

  2. Excepción (error de lógica)

Errores de sintaxis

Error de sintaxis. Ocurre cuando no se sigue la sintaxis correcta del lenguaje.

Un error de sintaxis ocurre cuando nos dejamos un paréntesis sin cerrar, los dos puntos tras la condición de un operador de decisión o iteración...

a = 2
if (a > 3 : 
    print(a)
  File "<ipython-input-1-539906e83b82>", line 2
    if (a > 3 :
              ^
SyntaxError: invalid syntax

Como podemos observar, ha saltado un error de sintaxis, SintaxError, debido a que nos hemos olvidado del paréntesis de cierre. Además, el propio error nos indica a qué es debido y dónde tenemos que modificar el código para corregir el fallo.

Excepciones

Excepción. Una vez superado el test de sintaxis, si la ejecución del programa es interrumpida, entonces estamos ante una excepción o error de lógica.

Una excepción puede deberse a intentar llamar a una variable que no ha sido declarada (NameError), intentar abrir un archivo que no se encuentra en la dirección indicada (FileNotFoundError), intentar dividir un número entre cero (ZeroDivisionError)... Siempre que se da alguna de estas situaciones, Python crea un objeto excepción. Si no es manejado correctamente, imprime un rastreo del error junto a algunos detalles sobre qué ha causado dicho error.

Como podemos observar, ha saltado una excepción, NameError, debido a que nos hemos llamado a una variable que no existe. Además, el propio error nos indica a qué es debido y dónde tenemos que modificar el código para corregir el fallo.

Excepciones de Python

Existen múltiples excepciones en Python que se nos muestran cuando se dan los errores correspondientes. Podemos mostrar por pantalla todas las excepciones de Python usando la función locals() tal y como se muestra a continuación

locals["__builtins__"] nos devuelve el módulo con las excepciones, funciones y atributos de Python. La función dir() nos permite listar todos esos elementos como strings.

Algunas de las excepciones de Python más comunes al programar son:

Excepción
Causa

ArithmeticError

Cuando falla una operación numérica

AssertionError

Cuando falla una declaración assert

AtributeError

Cuando falla una asignación de atributo o referencia

EOFError

Cuando la función input() llega a la condición fin de archivo (end-of-file)

FloatingPointError

Cuando falla una operación en coma flotante

ImportError

Cuando un módulo importando no es encontrado

IndentationError

Cuando la indentación no es correcta

IndexError

Cuando el índice de una secuencia se sale del rango

KeyError

Cuando una clave de un diccionario no es encontrada

KeyboardInterrupt

Cuando el usuario pulsa la tecla de interrupción

LookupError

Cuando el elemento no puede ser encontrado

MemoryError

Cuando una operación se queda sin memoria

NameError

Cuando se llama a una variable que no se encuentra a nivel global ni local

NotImplementedError

Cuando un método abstracto requiere de una clase heredada para sobreescribir el método

OverflowError

Cuando el resultado de una operación aritmética es demasiado grande para ser representado

RuntimeError

Cuando un error no entra dentro de ninguna categoría

TabError

Cuando la indentación consiste de tabulaciones y espacios en blanco inconsistentes

TypeError

Cuando a una función u operación se le suministra un objeto de tipo incorrecto

ValueError

Cuando una función obtiene un argumento del tipo correcto pero de valor incorrecto

ZeroDivisionError

Cuando el divisor de una división es 0

Manejo de excepciones

Como programadores, necesitamos ser lo más específicos posible. Esto implica ser conscientes de los errores que podrían ocurrir. Por suerte, Python permite a los programadores tratar con errores de forma eficiente.

Podemos manejar excepciones usando 5 sentencias:

  1. try / except

  2. try / finally

  3. assert

  4. raise

  5. with / as

1. try / except

  • El bloque try permite comprobar si hay errores de código.

  • El bloque except permite manejar el error.

En el siguiente chunk, en caso de que ocurra el error, imprimimos un mensaje por pantalla:

En el siguiente chunk, en caso de que ocurra el error, imprimimos el mensaje de la excepción correspondiente por pantalla:

Sin try /except, hubiéramos obtenido

Podríamos poner más de un bloque except

En el chunk anterior hemos intentado dividir un string entre 0. Por tanto, la execpción ya no se debe a intentar dividir entre 0, sino a otro motivo: que un string no puede ser el dividendo de la división.

También podemos combinar try / except con else:

El bloque else se ejecutará siempre y cuando no haya excepciones, junto al bloque try, tal cual ocurre en el ejemplo anterior.

2. try / finally

  • El bloque try permite comprobar si hay errores de código.

  • El bloque finally permite ejecutar el código a pesar del resultado de los bloques try y except.

Sea cual sea el caso, el bloque finally siempre se ejecuta.

El bloque finally puede ser útil para cerrar objetos y limpiar recursos.

3. assert

La palabra reservada assert se utiliza para debuguear el código. Nos permite comprobar si una condición en nuestro código devuelve True. De lo contrario, el programa nos devolverá un AssertionError

En el caso de que la condición devuelva False, podríamos indicar un mensaje del siguiente modo:

4. raise

Como programadores, podemos elegir cuando mostrar una excepción dada una condición. Para mostrar excepciones, usamos la palabra reservada raise

En el chunk anterior hemos usado raise para mostrar una excepción. No obstante, podemos elegir qué tipo de excepción mostrar y el texto que imprimir al usuario:

5. with / as

La palabra reservada with se utiliza para manejar excepciones y conseguir así un código más limpio y legible. Simplifica el manejo de recursos comunes tales como flujos de archivos.

En el siguiente chunk no utilizamos la palabra reservada with

Mientras que en el siguiente sí que utilizamos with / as y observamos que el código queda mucho más limpio y legible.

Ambos chunks de código darían el mismo resultado. No obstante, el segundo tiene menos líneas de código, pues entre otras cosas no le hace falta la línea file.close(), tal cual vimos en el tema anterior.

La palabra reservada with se asegura la adquisición y liberación adecuadas de recursos.

REPASO

Ejercicio 1

Dada la función divisors(), asegura con assert que el parámetro n se trata de un número entero positivo. De lo contrario, muestra como mensaje que "n debe ser de tipo int y debe ser mayor que 0"

Ejercicio 2

Dada la función divisors(), muestra TypeError con el mensaje correspondiente si el parámetro n no se trata de un número entero y muestra ValueError con el mensaje correspondiente si n no se trata de un número positivo.

Ejercicio 3

Dada la función is_palindrome(), asegura con assert que el parámetro word se trata de una variable de tipo string. De lo contrario, muestra como mensaje que "word debe ser de tipo string".

Ejercicio 4

Dada la función is_palindrome(), muestra TypeError con el mensaje correspondiente si word no se trata de una variable de tipo string.

Ejercicio 5

Dada la función is_palindrome(), muestra ValueError con el mensaje correspondiente si word no se trata de una palabra. Es decir, si una vez ha pasado la comprobación de ser una variable de tipo string, comprueba que no tiene espacios.

Ejercicio 6

Dada la función is_palindrome() del resultado del ejercicio anterior, modifícala de modo que acepte no solo palabras sino también frases y devuelva si el string introducido es palíndromo o no. Recuerda tener en cuenta la excepción TypeError junto al mensaje correspondiente.

Ejercicio 7

Utiliza try / except para dado un objeto de Python guardado en la variable x, aplicarle el método .index() y localizar el elemento "c". En el bloque try, guarda el resultado en la variable result. En el bloque except, en la variable result, si el objeto x es una lista, guarda el mensaje "La lista no tiene el elemento "c". En caso contario, guarda el mensaje "El objeto {tipo del objeto que sea x} no tiene el método .index()". Finalmente, imprime por pantalla el resultado.

Ejercicio 8

Crea una función que calcule el área de un cuadrado. Como parámetro se recibirá un número real, correspondiente a la longitud de la base. Lanza las excepciones pertinentes siempre que el parámetro no se trate de un número real o entero positivo.

Ejercicio 9

Crea una función que solicite al usuario la edad. Lanza una excepción en caso de que no se trate de una edad válida. Se considera edad no válida una edad negativa o mayor a 150. En cada caso, lanza el mensaje correspondiente.

Ejercicio 10

Crea una función que solicite al usuario una letra en mayúscula. Lanza una excepción en caso de que el usuario no haya introducido nada, no haya introducido una letra, no haya introducido una letra mayúscula o no haya introducido solamente un caracter.

Last updated