Curso Python. Volumen XIII: Excepciones. Parte I

Escrito por Javier Ceballos Fernández
Programación
0

Bienvenidos un día más al curso de Python, hoy os vamos hablar sobre los errores de ejecución y cómo los podemos controlar de modo que el programa siga ejecutándose, o si por el contrario, queremos que muestre el error que se ha producido de manera que podamos solucionarlo. Lo vamos a dividir en 2 partes ya que hay muchas cosas que asimilar. Así que pongámonos manos a la obra.

Los errores de ejecución son llamados comúnmente excepciones. Durante la ejecución de un programa puede surgir una excepción dentro de una función y que ésta no la maneje, entonces la excepción se propaga hacia la función que la invocó, si esta otra tampoco la maneja, la excepción continúa propagándose hasta llegar a la función inicial del programa y si esta tampoco la maneja se interrumpe la ejecución del programa. Entonces, ¿cómo se realiza el manejo de excepciones?

Manejo de excepciones

Para el manejo de excepciones Python utiliza las siguientes palabras reservadas: “try”, “except”, “finally”. Con estas palabras reservadas podremos crear diferentes bloques de código de manera que podamos manejar estas excepciones y así evitar que se produzca la interrupción del programa o, al menos, podamos realizar algunas acciones adicionales antes de que el programa se interrumpa.

Dentro del bloque “try”, pondremos el código que puede generar una excepción. A continuación de este bloque de código pondremos “except”, ya que se encargará de recoger la excepción generada y podamos tratarla de la manera adecuada

Voy a poneros un ejemplo para que veáis a lo que me refiero. Vamos a realizar una división por 0 (algo que sabemos que no se puede hacer) y trataremos la excepción de modo que la aplicación continúe y el usuario pueda corregir.

dividendo = 4
divisor = 0
dividendo / divisor

Resultado:

Como veis, si ejecutamos el código sin el tratamiento de excepción nos devuelve el error “ZeroDivisionError” ya que como sabemos esta división no se puede realizar. Para evitar que se genere la excepción y se detenga la ejecución, vamos a utilizar los bloques “try” y “except”, que acabamos de comentar.

dividendo = 4
divisor = 0
try:
    cociente = dividendo / divisor
except:
    print('No se permite la división entre cero')

Resultado:

Como podéis comprobar el programa no se interrumpió y nos mostró un mensaje personalizado para que el programa siga ejecutándose, en el ejemplo del capítulo anterior, lo teníamos colocado en la apertura del fichero y lo que hicimos era crearlo si no existía para que la ejecución pudiera continuar.

Dentro de un bloque “try” se pueden generar muchos tipos de excepción y tendremos que controlar todas las que nos sean necesarias. Para poder realizar esto tendremos que especificar a continuación de la palabra reservada “except” el nombre de la excepción que se pretende capturar. Un mismo bloque “except” puede atrapar varios tipos de excepciones, lo cual se hace especificando los nombres de las excepciones separados por comas a continuación de la palabra “except”. Es importante destacar que si bien luego de un bloque “try” puede haber varios bloques “except”, se ejecutará, a lo sumo, uno de ellos.

try:
    #
    # aquí ponemos el código que puede generar excepciones
    #
except IOError:
    #
    # entrará aquí en caso que se haya producido
    # una excepción IOError
    #
except ZeroDivisionError:
    #
    # entrará aquí en caso que se haya producido
    # una excepción ZeroDivisionError
    #
except:
    #
    # entrará aquí en caso que se haya producido    
    # una excepción que no corresponda a ninguno    
    # de los tipos especificados en los except previos
    #

Como se muestra en el ejemplo precedente también es posible utilizar una sentencia “except” sin especificar el tipo de excepción a capturar, en cuyo caso se captura cualquier excepción, sin importar su tipo. Cabe destacar, también, que en caso de utilizar una sentencia “except” sin especificar el tipo, la misma debe ser siempre la última de las sentencias “except”. Debido a que es la más genérica, si la pusiéramos la primera nunca capturaríamos las otras excepciones que son más específicas.

Por último, podemos ubicar un bloque “finally” donde se escriben las instrucciones de finalización, que son típicamente acciones de limpieza. La particularidad del bloque “finally” es que se ejecuta siempre, haya surgido una excepción o no. Si hay un bloque “except”, no es necesario que esté presente el “finally”, y es posible tener un bloque “try” sólo con “finally”, sin “except”.

Ya sabemos para qué sirven los bloques, pero ¿cómo actúa Python al encontrarse con ellos? Python comenzará a ejecutar las instrucciones que se encuentran dentro de un bloque “try”, si durante la ejecución de esas instrucciones se levanta una excepción, Python interrumpe la ejecución en el punto exacto en el que surgió la excepción y pasa a la ejecución del bloque “except” correspondiente.

Para ello, Python verifica uno a uno los bloques “except” y si encuentra alguno cuyo tipo haga referencia al tipo de excepción generada, comienza a ejecutarlo. Sino encuentra ningún bloque del tipo correspondiente pero hay un bloque “except” genérico, lo ejecuta. Al terminar de ejecutar el bloque correspondiente, se pasa a la ejecución del bloque “finally, si éste se encuentra definido.

Si por otra parte, no hay problemas durante la ejecución del bloque “try”, se completa la ejecución del bloque, y luego se pasa directamente a la ejecución del bloque “finally” (si éste está definido, de lo contrario el programa continuaría su ejecución).

Veamos todo esto con un ejemplo. Supongamos que nuestro programa tiene que procesar cierta información ingresada por el usuario y guardarla en un archivo. Dado que el acceso a archivos puede generar excepciones, siempre deberíamos colocar el código que manipula los archivos dentro de un bloque “try”. Después deberíamos colocar un bloque “except” que atrape una excepción del tipo “IOError”, que es el tipo de excepciones que generan la funciones de manipulación de archivos y podríamos agregar un bloque “except” sin tipo por si surge alguna otra excepción. Por ultimo deberíamos agregar un bloque “finally” para cerrar el archivo (haya surgido o no una excepción, siempre y cuando la aplicación vaya a finalizar).

try:

    archivo = open("miarchivo.txt")
    # procesar el archivo

except IOError:

    print('Error de entrada/salida.')
    # realizar procesamiento adicional

except:

    # procesar la excepción

finally:
    # si el archivo no está cerrado hay que cerrarlo
    if not(archivo.closed):

        archivo.close()

Esto es todo por hoy, en la próxima entrega os enseñaré más usos de las excepciones. Y para todos los que se acaban de incorporarse al curso indicarles que tenemos un índice con todos los capítulos del curso, ya que nunca es tarde para empezar.


Últimos análisis

Valoración RZ
10
Valoración RZ
7
Valoración RZ
9
Valoración RZ
10
Valoración RZ
8
Valoración RZ
10
Valoración RZ
9
Valoración RZ
9
Valoración RZ
10