Anuncios

Bienvenidos sean a este post, hoy desarrollaremos un tema que ya hemos visto anteriormente.

Anuncios
Anuncios

Cuando hablamos de excepciones nos referimos a basicamente errores, es decir cuando nosotros no encontrarmos un archivo, el tipo de dato enviado no coincide con el esperado o cualquier tipo de error que puede surgir en nuestro codigo el lenguaje no lo intrepreta como un error sino como una excepcion ocurrida y esto detendra el codigo pero no de forma grave, por ejemplo cuando vimos a next de los iteradores dijimos que este se detiene cuando encuentra la excepcion StopIteration o cuando trabajamos con try/except en el codigo de personalizacion de codificacion/decodificacion con JSON donde le deciamos que maneja a la excepcion en caso de error de tipo o clave, estos son errores de atributo (AttributeError), pero en este caso no lo detenia sino que lo maneja y continua con el mismo, aunque esta conducta es buena para determinados codigos (como mencionabamos en el caso del next) o para ser notificados cuando suceden los mismos, para entender este concepto vamos a ver unos ejemplos, comencemos con el primero:

>>> gen = (n for n in range(2))
Anuncios

Generamos un objeto donde guardamos unos rangos de numeros para utilizar next, vamos a ejecutar varias de estas funciones:

>>> next(gen)
0
>>> next(gen)
1
>>> next(gen)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>
Anuncios

Como pueden ver usamos el next para ver el proximo valor de gen hasta que llegamos a su fin y nos devuelve un StopIteration, vamos a ver algunos tipos de excepciones que podemos tener:

>>> print(sin_definir)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sin_definir' is not defined
>>>
Anuncios

Esta es una excepcion cuando intentamos mostrar una variable que no esta definida, veamos otra excepcion:

>>> miLista = [1,2,3]
>>> miLista[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>>
Anuncios

Aqui creamos una lista con tres valores y cuando queremos recuperar un indice que no existe nos informa que nos fuimos del rango, esta es una excepcion cuando trabajamos con listas y sin darnos cuenta nos pasamos de la cantidad de valores almacenados, veamos otra excepcion:

>>> miDicc = {'a':'A', 'b':'B'}
>>> miDicc['c']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'c'
>>>
Anuncios

En este caso tenemos un diccionario con varios valores y cuando le pedimos que nos traiga una clave que no esta nos devuelve la excepcion de tipo clave y cual es la no encontrada, otro error habitual de cuando trabajamos con ellos, veamos otra excepcion:

>>> 11 / 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>>
Anuncios
Anuncios

Esta excepcion es cuando dividimos un numero por cero, obviamente no lo haremos directamente pero en algunas ocasiones puede suceder que al trabajar con operaciones se nos escape y surja esta operacion, no ocurre habitualmente pero puede suceder y en algunos sistemas o lenguajes esto puede ser un error gravisimo, con esto hemos visto algunas de la excepciones mas normales que nos pueden suceder pero ahora vamos a centrarnos en como manejarlos y para esto usaremos un viejo conocido como es try/except, para entenderlo vamos a trabajar con un ejemplo y para ello primero crearemos la siguiente funcion:

>>> def sintaxis_try(num, den):
...     try:
...             print(f'En el bloque de try: {num}/{den}')
...             resultado = num / den
...     except ZeroDivisionError as zde:
...             print(zde)
...     else:
...             print('El resultado es: ', resultado)
...             return resultado
...     finally:
...             print('Saliendo')
... 
>>>
Anuncios
Anuncios

En esta funcion veremos la sintaxis del try y la utilizaremos, para este caso recibiremos dos valores para numerador (num) y denominador (den), dentro de esta funcion tenemos un bloque try donde mostraremos un mensaje indicando que estamos en el bloque del try y los valores informados, despues establecemos una nueva variable donde guardaremos la division entre ellos, despues tenemos un except donde manejaremos una excepcion, en este caso sera la division por cero, y en este caso mostraremos esta falla, luego seguiremos con un else donde mostraremos el valor de resultado y lo devolveremos, esto lo usamos asi para cuando no se cumple la excepcion, por ultimo tenemos un finally donde mostraremos el mensaje de salir, vamos a probarlo para ver el resultado:

>>> print(sintaxis_try(11, 0))
En el bloque de try: 11/0
division by zero
Saliendo
None
>>>
Anuncios

Aqui podemos ver que sucede cuando lo dividimos por cero, nos muestra el mensaje del bloque del try, luego la excepcion y el mensaje de finally, el None es debido al error, vamos a probarlo nuevamente:

>>> print(sintaxis_try(12, 4))
En el bloque de try: 12/4
El resultado es:  3.0
Saliendo
3.0
>>>
Anuncios

En este caso vemos el resultado, devolvio el valor de resultado y nos mostro el valor de finally a pesar de haber hecho un return antes, esto es debido a que finally siempre se va a ejecutar no importa lo que este antes, veamos como es su sintaxis basica:

try:
    ... instrucciones ...
except Excepcion:
    ... instrucciones ...
finally:
    ... instrucciones ...
Anuncios
Anuncios

Tiene dos bloques obligatorios que son try y except porque uno no puede usarse sin el otro, siempre comenzaremos con try y de este habra uno solo, seguido por uno o varios except, estos podemos repetirlo cuantos sean necesarios, dado que podemos manejar mas de una excepcion y el finally siempre va al final pero es opcional asi que podemos usarlo o no y equivale al else de if, dado que ejecutara las instrucciones una vez que haya terminado todo el codigo anterior, aunque este nos sirve como excepcion de lo comentado anteriormente dado que si no tenemos ningun except pasando el finally el codigo en try funcionara tambien, recuerden lo visto en este post, veamos por ultimo algunas formas de trabajar con varias excepciones:

try:
    ... instrucciones ...
except Excepcion1:
    ... instrucciones ...
except (Excepcion2, Excepcion3):
    ... instrucciones ...
except Excepcion4 as objeto:
    ... instrucciones ...
Anuncios

Podemos pasar la excepcion directa con sus respectivas instrucciones para procesar la excepcion, tambien podemos agruparlas para que actue en caso de ocurrir algunas de ellas (tal como vimos con JSON) o bien puede manejar una excepcion y esta asignarla a un objeto que podemos reutilizar en nuestro codigo para hacer alguna referencia, y como dijimos antes podemos utilizar todas las que sean necesarias no hay limite para ello, vamos a ver el ultimo tema.

Anuncios

En algunos posts mencionamos que «generamos» una excepcion y para ello usamos la funcion raise seguido de la excepcion que queremos que sucede, esto es util para hacerle crear al programa que ocurrio tal o cual excepcion y por ende debe tomar otra conducta, una funcion muy util es emprolijar nuestro codigo, vamos a ver un ejemplo:

>>> n = 100
>>> encontrado = False
>>> for a in range(n):
...     if encontrado: break
...     for b in range(n):
...             if encontrado: break
...             for c in range(n):
...                     if 42 * a + 17 * b + c == 5096:
...                             encontrado = True
...                             print(a, b, c)
... 
79 99 95
>>>
Anuncios
Anuncios

Establecemos una variable llamado n con un valor, luego otra llamada encontrado con el valor False, lo siguiente sera un bucle for con el rango establecido en n y almacena todo en a, dentro tiene un condicional donde si encontrado es True sale del programa, pero dentro de este bucle tenemos otro que hace lo mismo que el anterior y lo guarda en b, de vuelta tenemos otro condicional igual al ciclo anterior y otro bucle mas de la misma conducta donde guarda el valor en c, pero este tiene un condicional donde verifica si el valor de a multiplicado por 42 mas el valor de b multiplicado por 17 mas c es igual a 5096, en caso de cumplirse establece a encontrado como True y nos muestra los valores de las tres variables, como podemos ver es un codigo funcional pero completamente opuesto a lo que promueve python, para ello vamos a modificar el codigo de la siguiente manera y para ello primero crearemos la siguiente clase:

>>> class ExcepcionSalirLoop(Exception):
...     pass
... 
>>>
Anuncios

Esta clase la usaremos para que salga del bucle y sera del tipo Exception para poder trabajar con ella en nuestro codigo, lo siguiente sera usar el siguiente codigo dentro del bloque try y agregar un except:

>>> try:
...     n = 100
...     for a in range(n):
...             for b in range(n):
...                     for c in range(n):
...                             if 42 * a + 17 * b + c == 5096:
...                                     raise ExcepcionSalirLoop(a, b, c)
... except ExcepcionSalirLoop as esl:
...     print(esl)
... 
(79, 99, 95)
>>>
Anuncios
Anuncios

Aca agregaremos un bloque try/except, en el try agregaremos a n con el mismo valor pero sin la variable encontrado, y los tres bucles anteriores pero sin los condicionales donde chequeaban encontrado para salir y en el condicional del ultimo bucle en lugar de cambiar el valor de encontrado y mostrar los valores utilizamos un raise para que un genere un error con la clase que creamos anteriormente y recibira los tres valores de los bucles, en el except le pasaremos la clase que usamos como excepcion, a este la pasamos a una objeto y dentro del bloque mostraremos los valores que almacenamos anteriormente, como pueden ver no solo nos quedo un codigo mas legible y no repetimos nada de manera innecesaria sino que tambien que quedo mas practico y acorde a la filosofia de python.

Anuncios

En resumen, hoy hemos hablado de excepciones, que son, como trabajan, que podemos manipular con ellas, como nos benefician en la conducta de nuestros codigos, como es su sintaxis mas basica, y como podemos manipular varios tipos de excepciones con un bloque try, por ultimo hemos visto como podemos generar un error acorde a nuestras necesidades, espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50