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

Retro

Lugares

Redes

Sistemas

Varios