Logo Python Fundamentos de la programación (Python)

[M10] Excepciones

Los errores que se pueden presentar en un programa son: de sintaxis (detectados por el intérprete), de semántica (el programa no funciona correctamente), o de ejecución (excepciones).

En este módulo trabajaremos con excepciones. Una excepción es una estructura que permite realizar el manejo de errores en un programa, los cuales pueden causar que la ejecución del mismo se detenga.

Existen diferentes tipos de error que se pueden interceptar, por ejemplo tratar de utilizar un valor tipo string en lugar de un número en una función, importar módulos inexistentes, problemas con la manipulación de archivos externos, etc.

Contenido


Definir una excepción

Para definir una excepción en Python se utiliza el par de palabras claves try - except, que enmarcan dos bloques de instrucciones. El primero, el bloque try indica el bloque de instrucciones de la función. El segundo, el bloque de instrucciones que se ejecutará si se genera un error.

Ejemplo: La siguiente función realiza la división de dos números excepto cuando el divisor es igual a cero:

def dividir(dividendo, divisor):
try:
cociente = dividendo / divisor
return cociente
except:
print('No es posible realizar una división entre cero.')

# UTILIZACION DE LA FUNCION
print(dividir(10,2))
>>> 5.0

print(dividir(3,0))
>>> No es posible realizar una división entre cero.
>>> None

La cláusula except

Como seguramente habrás experimentado, cuando ocurre un error durante la ejecución de un programa, Python crea una excepción.
Si ésta excepción no se controla, la ejecución del programa se detiene y se muestra el error (traceback). Ejemplo:

Traceback (most recent call last):
   File "<excepciones1.py>", line 6, in <module>
      print(dividir(3/0))
   File "<excepciones1.py>", line 2, in <module>
      cociente = dividendo/divisor
ZeroDivisionError: division by zero

Errores más usuales:

Los errores más usuales que generan las siguientes excepciones en Python son:

En el siguiente enlace podrás consultar el nombre de todas las excepciones incorporadas de Python

Dado que dentro de un mismo bloque try pueden producirse excepciones de distinto tipo, es posible utilizar varios bloques except, cada uno para capturar un tipo distinto de error.

Utilizaremos un texto como argumento para el parámetro dividendo para ejemplificarlo:

def dividir(dividendo, divisor):
try:
cociente = dividendo / divisor
return cociente
except ZeroDivisionError:
print('No es posible realizar una división entre cero.')

except TypeError:
print('El dividendo y el divisor deben ser valores numéricos.')

# UTILIZACION DE LA FUNCION
print(dividir(10,2))
>>> 5.0

print(dividir(3,0))
>>> No es posible realizar una división entre cero.
>>> None

print(dividir('5',1))
>>> El dividendo y el divisor deben ser valores numéricos.
>>> None

En caso de utilizar una cláusula except sin especificar el tipo de error, la misma debe ser siempre la última de las sentencias except. Esto es posible, pero no es una práctica recomendable, ya que no podremos tener conocimiento sobre el tipos de error ocurrido.

La palabra reservada Exception

La cláusula except puede interceptar el tipo de error ocurrido guardando la excepción en una variable. Esto permite conocer el tipo de error que se ha generado. La variable, a la derecha de la palabra reservada as (en el caso del ejemplo, la variable se llama error), guardará el mensaje de error el cual posteriormente, será impreso. La sintaxis es la siguiente:

except Exception as error
print('Se ha generado el tipo de error:\n', error)

El resultado del bloque, sería el siguiente, si se desea dividir '5 entre 1:

print(dividir('5',1))
>>> Se ha generado el tipo de error:
     unsupported operand type(s) for /: 'str' and 'int'
>>> None

La cláusula else

El bloque else se ejecutará solo si el bloque try se ejecuta sin errores. Esto puede ser útil cuando se desee continuar el código del bloque try . Por ejemplo: 1) Se ordena abrir un archivo en el bloque try, 2) Se verifica si hay errores 3) De no haberlos, se lee su contenido dentro del bloque else. El ejemplo se muestra a continuación:

try:
documento = open('datos/mi_archivo.txt')
except FileNotFoundError:
print('Lo siento, el archivo no existe')
else:
contenido = documento.read()
print(contenido)
documento.close()

La cláusula finally

Python verifica uno a uno los bloques except y si encuentra alguno cuyo error haga referencia al tipo de excepción levantada, comienza a ejecutarlo. Sino encuentra ningún bloque del tipo correspondiente pero hay un bloque except sin un tipo de error o que lea la excepción y la pase a una variable, lo ejecuta. Al terminar de ejecutar el bloque correspondiente, se pasa a la ejecución del bloque else, si se encuentra definido. Finalmente, el bloque finally siempre es ejecutado sin importar que pase en los otros bloques. Ejemplo:

try:
documento = open('datos/mi_archivo.txt')
except FileNotFoundError:
print('Lo siento, el archivo no existe')
else:
contenido = documento.read()
print(contenido)
documento.close()
finally:
# verifica si el archivo está cerrado, si no, lo cierra
if not(documento.closed):
documento.close

Sintaxis de las excepciones

A continuación se resume la forma y el orden en el cual se deben indicar las cláusulas para el manejo de errores. En Python es posible utilizar tantos bloques except como se desee para un bloque try. De esta forma se puede realizar un procedimiemto diferente para cada tipo de error. Los bloques else y finally son opcionales. En el bloque else se escriben todas aquellas líneas de código que se deseen ejecutar cuando no ocurra ningún error. En el bloque finally, todas las instrucciones que deseemos ejecutar, independientemte de si ocurrió o no un error.

try:
# Instrucciones de la función
except nombre de excepción:
# Se indican las instrucciones que se ejecutarán
# si el error se corresponde con un tipo de excepción determinada por Python
except exception as error:
# también podemos guardar el error en una variable (en este caso llamada error)
# para posteriormente imprimirlo
except:
# instrucciones que se ejecutan para cualquier tipo de error
# (se usa preferiblemente el formato anterior y debe ir al final de todos los bloques except)
else:      # opcional
# bloque adicional de instrucciones si no hay excepciones
finally:   # opcional
# instrucciones que se deben ejecutar sin importar si se produce una excepción o no