Python: Excepciones
Cuando se produce un error (sea cual sea) se genera una excepción y se para el programa, lo cual puede ser un problema, pero podemos "capturar" esos errores/excepciones y realizar acciones como por ejemplo generar un log o aviso del error, o ejecutar cierto código en su defecto.
try : suite1 except [expression [as identifier]: ⌉ Se puede repetir 1 suite2 ⌋ o más veces [else: ⌉ opcional suite3] ⌋ [finally: ⌉ opcional suite] ⌋
Se ejecuta el primer bloque de código suite1
, si se produce un error se examina la expresión del except
para ver si coincide la expresión (error producido) y si es así se ejecuta su bloque de código suite2
, si no se pone expresión se ejecuta igualmente. Pueden haber más de un bloque except
para ejecutar un bloque de código diferente por cada error/excepción.
La cláusula else
opcional se ejecuta si el flujo de control abandona el bloque de código suite1
siempre que no se genere ninguna excepción y no se ejecute return
, break
o continue
. Las excepciones en la cláusula else
no son manejadas por las cláusulas de excepción anteriores.
El bloque finally
, que es opcional, se ejecuta siempre haya o no un error/excepción.
In [1]: dict = {} In [2]: dict['clave'] --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-2-ea2c43670eae> in <module>() ----> 1 dict['clave'] KeyError: 'clave'
Aquí podemos ver que se genera un error/excepción al acceder a una clave que NO existe, indicando la expresión KeyError
(que es la que usaremos para except
.
In [1]: dict = {} In [2]: try: print("antes del error") dict['clave'] print("esto NUNCA se ejecuta") except KeyError: print("se ha producido un error") antes del error se ha producido un error
Aquí podemos ver que una vez que se produce un error todas las líneas de código siguientes NO se ejecutan y saltan al bloque del except
.
Este bloque SOLO se ejecuta si el bloque de código suite1
del try
se ejecuta SIN errores además de que no se ejecute return
, break
o continue
. Las excepciones en la cláusula else
no son manejadas por las cláusulas de excepción anteriores, un ejemplo:
try: f = open('fichero.txt') except IOError: print("Fichero no existe.") else: print("Fichero existe")
Intentamos abrir el fichero, si existe, lo abre y muestra "Fichero existe", si no, el fichero no se abre y se muestra "Fichero no existe".
In [1]: dict = {} In [2]: try: print("antes del error") dict['clave'] print("esto NUNCA se ejecuta") except KeyError: print("se ha producido un error") finally: print("Esto siempre se ejecuta haya o no excepción") antes del error se ha producido un error Esto siempre se ejecuta haya o no excepción
Aquí podemos ver que una vez que se produce un error todas las líneas de código siguientes NO se ejecutan y saltan al bloque del except
. Además se ejecuta el bloque de finally
.
In [1]: dict = {} In [6]: try: print("antes del error") dict['clave'] = 2 print("esto AHORA se ejecuta") except KeyError: print("se ha producido un error") finally: print("Esto siempre se ejecuta haya o no excepción") antes del error esto AHORA se ejecuta Esto siempre se ejecuta haya o no excepción
Aquí vemos que al no producirse un error, se ejecutan todas las líneas de código ignorando el bloque del except
y además se ejecuta el bloque de finally
.
Cuando se produce un error seguramente queramos saber que ha pasado, ya sea para guardar un log o mandar un aviso o ejecutar cierto código dependiendo del error.
In [1]: dict = {} In [2]: try: print("antes del error") dict['clave5'] print("esto NUNCA se ejecuta") except KeyError as mi_error: print("se ha producido un error") print("representacion = ", repr(mi_error)) print('cadena = ', str(mi_error)) antes del error se ha producido un error representacion = KeyError('clave5',) cadena = 'clave5'
Lo interesante aquí es str(mi_error)
que nos indica que es lo que ha producido el error, en este caso el índice qu eNO existe en el diccionario.
Un truco es poner como última excepción la excepción llamada Exception
y dentro de ella scar el nombre de la excepción con type(nombre_excepcion).__name__)
.
In [1]: try: print(5/0) except Exception as nombre_excepcion: print("Ha ocurrido una excepción de tipo:", type(nombre_excepcion).__name__) Ha ocurrido una excepción de tipo: ZeroDivisionError
Más información en: try, Errores y excepciones, excepciones de Python