¿Qué son las excepciones? Las excepciones son errores que ocurren durante la ejecución del programa. Estos errores no son necesariamente fatales sino que se pueden manejar, es decir, que se pueden realizar una o más acciones cuando ocurre dicho error. Las excepciones son de un tipo y Python define muchos tipos de excepciones. Algunas ejemplos son: "ZerodivisiónError" que ocurre cuando hay una división por cero, "NameError" que ocurre cuando un nombre local o global no es encontrado, "TypeError" que ocurre cuando una operación o una función es aplicada a un objeto de un tipo no apropiado. Ante una exepción caben dos posibilidades, manejarlas o no manejarlas. Si durante la ejecución de un programa, dentro de una función, ocurre una excepción y la función no la maneja, la excepción se propaga hacia la función que la invocó. Si esta otra función tampoco la maneja, la excepción continúa propagándose hasta llegar a una función inicial del programa y si ésta tampoco la maneja, se interrumpe la ejecución del programa dando un error de ejecución. Veamos como manejar excepciones. Los lenguajes de programación proveen algunas palabras reservadas para manejar las excepciones. Manejar una excepción nos permitirá realizar acciones de recuperación para evitar la interrupción del programa, o realizar algunas acciones antes de que se interrumpa el programa o simplemente mostrar un mensaje más claro de lo que ocurrió y por qué ocurrió. En Python el manejo de excepciones se hace mediante los bloques que utilizan las sentencias: "Try", "Except" y "Finally". Dentro del bloque "Try" se ubica todo el código que pueda llegar a levantar una excepción. El término "levantar" se utiliza para referirse a la opción de generar una excepción. A continuación se ubica el bloque "Except" que se encarga de capturar la excepción y nos da la posibilidad de manejarla mostrando, por ejemplo, un mensaje adecuado del usuario. El bloque "Finally" es opcional y se coloca a continuación del bloque "Except", indicando las acciones que hay que realizar después del código del bloque "Tray", haya ocurrido una excepción o no. Adicionalmente, existe un bloque opcional, "Else", que se ejecuta cuando el código de bloque "Tray" no levanta una excepción. Este bloque es útil para poner en el bloque "Tray" sólo el código donde se espera la excepción que se está capturando en el bloque "Except". Así como pueden ocurrir excepciones y manejarlas, en nuestros programas podremos levantar excepciones cuando sea necesario. Para esto, Python nos provee la declaración "Raise" que permite al programador forzar a que ocurra una excepción específica. La declaración "Raise" puede recibir un argumento que tiene que ser la instancia de una excepción o de una clase de excepción, es decir, una clase que hereda de la clase base "Exception" que provee Python. Cabe destacar que las excepciones cambian el flujo de ejecución del programa porque será propagada a la función que llamó a la función, que levantó la excepción. Por último, tenemos la posibilidad de crear nuestros propios tipos de excepciones. Para esto nuestro tipo de excepción tiene que heredar de la clase base "Exception" directa o indirectamente. Para resumir todo esto, las excepciones son errores en la ejecución del programa. No todos los errores terminan en la ejecución del programa, sino que podemos manejar las excepciones para que el programa se recupere y no tenga que interrumpir su ejecución con un error. Además, es útil levantar excepciones en las funciones que realizamos para que quede explícito los errores que pueden ocurrir y el que utiliza nuestra función pueda manejarlos si lo desea. Y podemos crear nuestros propios tipo de excepciones para darle más semántica al error que estamos levantando.