Algo que siempre va a pasar cada vez que programamos es cometer errores, la mayoría de veces sorteamos esos errores dándole al compilador o al intérprete lo que necesita para que se calle, pero ¿Y qué tal si en lugar de que el intérprete nos controle, porque no lo hacemos nosotros al decirle que hacer con esos errores? ¡Siiiii! ¡Que se meta sus errores por el cu#0!
En esta oportunidad vamos a aprender a sortear esos errores a través de excepciones y evitar así que el programa pare su ejecución.
Esta vez en lugar de escribir trozos de código, lo haré de una vez con todo el código de ejemplo.
class EqualNumberException(Exception):
def __init__(self, mensaje):
self.message = mensaje
def main(args):
try:
x = int(input("Ingrese un numero: "))
print(x,"Es un numero entero")
y = 12
if x == y:
raise EqualNumberException('Identicos')
except ZeroDivisionError as zde:
print(f"tipo: {type(zde)}, error: {zde}")
except (ValueError,TypeError) as vte:
print(f"tipo: {type(vte)}, error: {vte}")
except NameError as ne:
print(f"tipo: {type(ne)}, error: {ne}")
except Exception as e:
print(f'tipo: {type(e)}, error: {e}')
else:
print("No arrojo ninguna excepcion")
finally:
print(12/x)
print("Esta linea se ejecuta si o si", "el valor de x es:",x)
print('Continuamos'.center(30,'-'))
return 0
if __name__ == '__main__':
import sys
sys.exit(main(sys.argv))
En primer lugar ignoren lo de crear una función #main con argumentos, es un estilo habitual que me gusta usar y que en un futuro explicaré para qué sirve, por el momento voy a explicar que hacen cada una de las palabras reservadas
try, except, else, finally.
Estas palabras reservadas se usan cada una con bloques de código indentados, similar a if, else o a for y while
try: Es una palabra reservada donde inicializamos el bloque de código que queremos examinar, si ocurre un error saltará inmediatamente a una línea #except.
except: Esta palabra reservada seguida del tipo de error, permite guardar el tipo de excepción en una variable temporal que usaremos si lo deseamos para imprimir algún o usar como retorno.
Si deseamos usar mas de una clase de excepción podemos separarlas por comas y guardarlas en una variable, en dicha variable se guardará la primera que encuentre y el bloque de código se ejecutara si atrapa algún tipo de excepción separado por comas.
else: al igual que en el bloque if, else se usa para cuando ya se encuentren excepciones, pueda ejecutar un bloque de código por defecto.
finally: se usa para ejecutar bloques de código sin importar si encuentra o no errores o excepciones, normalmente su uso está dado para eliminar alguna variable o clase, cerrar archivos abiertos o descargar la memoria.
Tipos de errores.
Hay varios tipos de errores, cada tipo de error en sí es una clase y la mayoría hereda de la clase #Exception y a su vez esta hereda de #BaseException, con el siguiente gráfico se puede explicar la jerarquía de clases en las excepciones.
Cuando aplicamos los distintos bloques #except es mejor empezar por los tipos de excepciones mas específicos, o sea las clases hijas y poco a poco ir subiendo a las clases mas genéricas, o sea las clases padres.
No hay mucho que explicar, pues cada error se explica por si solo y lo mas seguro ya han lidiado con mucho con distintos tipos de errores.
Creando nuestras excepciones.
Lo primero es crear nuestra propia clase que herede de #Exception, con un parámetro de mensaje.
class EqualNumberException(Exception):
def __init__(self, mensaje):
self.message = mensaje
En este ejemplo vamos a arrojar una excepción cuando dos números sean iguales.
try:
x = int(input("Ingrese un numero: "))
y = 12
if x == y:
raise EqualNumberException('Identicos')
except Exception as e:
print(f'tipo: {type(e)}, error: {e}')
Dentro del bloque try, comparamos si x es igual a y, dentro del bloque de comparación usamos la palabra reservada #raise que nos sirve para levantar excepciones, ya sean propias o nativas del lenguaje, opcionalmente con un mensaje, en este caso obligatorio porque olvidé un valor por defecto dentro de la clase, pero para las excepciones nativas no es necesario un mensaje.
Para ejecutar la excepción bien podemos hacerlo a través de 'except Exception' si queremos que sea capturado de forma genérica o 'except EqualNumberException' si queremos que lo capture de manera específica.
Por último se recomienda que todas las excepciones personalizadas que hagamos estén dentro del mismo archivo y que de este módulo se desprenda todas las excepciones para todas las distintas partes del programa.
Esto es todo por ahora, no fue un tema muy largo. Recuerden que el manejo de excepciones su principal utilidad es evitar que se detenga la ejecución del programa, personalmente pienso que es mejor tener el control de los datos y hacer lo posible para procesarlos, porque a través del manejo de excepciones podemos perder el control de los errores y tener quizás comportamientos indeseables.
En contraposición tenemos que el manejo de errores, sobre todo los que hagamos por nuestra parte, puede ser útil por ejemplo para indicarle al usuario que está ejecutando un método de una clase que aún no ha inicializado y aprovechar para lanzar mensajes mas específicos acerca de los datos que está aportando a nuestra API, librería o módulo.
No siendo mas nos vemos en un próximo post.
Comments