Hasta ahora hemos visto como las excepciones nos permiten controlar los posibles errores que pueden ocurrir en nuestro código. Sin embargo, dentro de la comunidad de Python tienen otro uso: control de flujo.
En este momento ya debes estar familiarizado con las estructuras de control flujo que ofrece Python (if... elif...else); entonces, ¿por qué es necesaria otra modalidad para controlar el flujo? Una razón muy específica: el principio EAFP (easier to ask for forgiveness than permission, es más fácil pedir perdón que permiso, por sus siglas en inglés).
El principio EAFP es un estilo de programación común en Python en el cual se asumen llaves, índices o atributos válidos y se captura la excepción si la suposición resulta ser falsa. Es importante resaltar que otros lenguajes de programación favorecen el principio LBYL (look before you leap, revisa antes de saltar) en el cual el código verifica de manera explícita las precondiciones antes de realizar llamadas.
Veamos ambos estilos:
# Python
def busca_pais(paises, pais):
"""
Paises es un diccionario. Pais es la llave.
Codigo con el principio EAFP.
"""
try:
return paises[pais]
except KeyError:
return None
// Javascript
/**
* Paises es un objeto. Pais es la llave.
* Codigo con el principio LBYL.
*/
function buscaPais(paises, pais) {
if(!Object.keys(paises).includes(pais)) {
return null;
}
return paises[pais];
}
Como puedes ver, el código de Python accede directamente a la llave y únicamente si dicho acceso falla, entonces se captura la excepción y se provee el código necesario. En el caso de JavaScript, se verifica primero que la llave exista en el objeto y únicamente con posterioridad se accede.
Es importante resaltar que ambos estilos pueden utilizarse en Python, pero el estilo EAFP es mucho más "pythonico".
Siento que acá todos son expertos, yo tengo que leer las cosas unas 5 veces para entender un poco de lo que habla.
Son palabras que literalmente se que dice, pero no hay una figura imaginativa en mi cerebro, esta totalmente en blanco.
Así empieza la curva de aprendizaje para cualquier tema nuevo. Estoy en la misma situación pero por experiencias pasadas sé que se vuelve más sencillo con la práctica. Ánimo!
Tranquilo Rafael, nos ha pasado a todos.. yo hace un par de años que empecé a meterme al tema del software por mi cuenta pero nunca pude dedicarme realmente como ahora y te puedo asegurar que he aprendido un montón, he tenido dudas y he tenido por ahí que recurrir a otras fuentes o al lápiz y al papel mas de una vez.. ánimos, a no bajar los brazos que con tiempo, estudio y práctica todo se aprende. Qué es lo que no entiendes? Comentame así te ayudo a entenderlo.
Intente hacer un poco más dinámica esta parte e implementar lo que ha habiamos visto de diccionarios espero les sirva, aún me faltan implementar algunas cosas.
anime ={'Shounen':'Naruto','Mecha':'Zoids','Vampiros':'Hellsing','Espacio':'Terra formars','Demonios':'Kimetsu no Yaiba','Deportes':'Capitan Tsubasa','Comedia':'Ranma 1/2','Romance':'Kimi no na wa',}def buscar_en_diccionario(diccionario,llave):try:returnprint(diccionario[llave]) except KeyErrorase:print(e)return(f'{llave} no se encontro en el diccionario')def actualizar_genero_diccionario(diccionario,llave,valor): diccionario.update({llave:valor})returnprint(f'El diccionario ha sido actualizado \nLos generos son: {diccionario.keys()}')def eliminar_valor_de_un_genero(diccionario,llave):try: diccionario_temp ={k:('Sin valor de llave'if diccionario.get(llave)==v else v)for k,v in diccionario.items()} diccionario.update(diccionario_temp)returnprint(f'Hola {diccionario.values()}') except NameErrorase:print(e)returnprint(f'{llave} incorrecta')def manipular_dict(diccionario):print(f'Animes disponibles: {diccionario.values()}')print('Menu \n1. Buscar genero \n2. Actualizar Genero y anime \n3. Eliminar una anime') seleccion_menu =int(input('Seleccione un número del menu: '))if seleccion_menu ==1: llave =str(input('Seleccione genero que desea buscar: ')) llamar_funcion =buscar_en_diccionario(diccionario,llave)returnmanipular_dict(diccionario) elif seleccion_menu ==2: llave =str(input('Seleccione genero que desea agregar: ')) valor =str(input('Seleccione anime que desea agregar al genero: ')) llamar_funcion =actualizar_genero_diccionario(diccionario,llave,valor)returnmanipular_dict(diccionario) elif seleccion_menu ==3: llave =str(input('Seleccione genero del anime que desea eliminar: ')) llamar_funcion =eliminar_valor_de_un_genero(diccionario,llave)returnmanipular_dict(diccionario)else:print('No se encontró número en el menu')returnmanipular_dict(diccionario)x =manipular_dict(anime)
Intentar hacer el mismo programa con switch(maneja menor las opciones) y te quedara perfecto, gracias compañero.
muy interesante.
Digamos que en un buffet
El principio EAFP
Cada uno se sirve su ración y se confía que solo agarres un postre
El principio LBYL
Te sirven solo una ración de postre y punto.
Creo que la analogía del buffet se aleja un poco del significado de EAFP y LBYL.
Estos estilos permiten "asumir" que un error podría ocurrir. En este caso, al buscar con una llave un valor en un diccionario/objeto.
Por ejemplo, asumiendo que el diccionario/objeto tiene 150 elementos (enumerados del 1 al 150) y por "accidente" se envía un 9999, la función está preparada para decir "Oye viejo, tu llave está muy bonita y todo pero no tengo un valor de país con dicha llave"; a simplemente dejar de funcionar.
**Es más fácil pedir perdón: **(Desarrollador porque agregaste esa excepción?! Pero bueno, nos salvó el día tu suposición)
A pedir permiso: (Oiga jefecito, me da chance de escribir este control de excepción? :( ).
Saludos!
Interesante, me dejas pensando como lo podría aplicar a buffet :)
EAFP:
try: x = my_dict["key"]except KeyError: # handle missing key
LBYL:
if"key"inmy_dict: x = my_dict["key"]else: # handle missing key
La versión LBYL tiene que buscar la clave dentro del diccionario dos veces y también podría considerarse un poco menos legible.
Me parece curioso tu código ya que noté que usaste el estilo EAFP para la función busca_pais() y también usaste implícitamente el estilo LBYL para poder imprimir el retorno.
Gran ejemplo para entenderlo :D
Script completo EAFP en Python :snake: :smiley:
def busca_pais(paises, pais):"""
Paises es un diccionario.País es la llave.Código con el principio EAFP."""
try:return paises[pais] except KeyError:returnNonedef run(): paises ={'Mexico':1,'Argentina':2,'Colombia':3} pais =input('Ingrese su pais: ')print(busca_pais(paises, pais))if __name__ =='__main__':run()
le falto una coma al 3
me sirvio para practicar tu codigo, gracias!
Me alegra esa es la intención, poder ayudar :smiley:
Como dice la info, el estilo EAFP es más pythonico, sin embargo, para efectos de ilustración creo que esto podría servir
if pais not in paises.keys():returnNonereturn paises[pais]
En LBYL, en la función built-in de los diccionarios llamada "keys" se obtiene un iterador, donde se evalúa si existe o no el key, cabe destacar, que en esta implementación me basé en el código escrito en JavaScript.
Cuando digo "donde se valúa si existe o no el key", me refiero a esta implementación del método en el if que se puede observar, no me refiero a que la función realiza la evaluación.
Python es muy elegante, se tenia que decir y se dijo.
De acuerdo!
Ohh siii
EAFP es in ingles(es mas fácil pedir perdón que pedir permiso) es mas pythonico
LBYL revisa antes de salta jastripeico
python es un adolescente audaz mientras a java es un viejo precavido
Me quedo mas claro con este comentario :)
Java es horrible, mas feo que C jajaja
Me parece mucho mas fácil el estilo EAFP, punto para Python 😂😂
realmente en Javascript el codigo no esta mal, pero parece hecho por alguien no especializado en javascript.
la representacion real seria algo asi:
si el pais existe, lo retorna, de lo contrario devuelve null.
es verdad Alejandro me parecio muy raro ese codigo en js jajajaja
pythonico :)
jajajaja es más fácil pedir perdón que permiso
Me gusto el uso de la palabra "pythonico"
yo soy programador de C# se me hace más natural el estilo de LBYL
Grace Hopper
_ «Si es una buena idea, continuad y llevadla a término. Es mucho más fácil pedir disculpas que conseguir el permiso necesario»_
pregunta para puntos
Realmente quiere preguntar algo?
O solo intenta subir el platzi rank?
.
De ser así, es mucho fácil otras cosas como
Generar aportes de valor que hagan que la gente de like
Hacer una pregunta interesante que habrá un debate sobre el tema
Hacer un tutorial o un porte
Tomar los exámenes de los cursos y las rutas
…
En cada una de las clases vi la misma “pregunta”, (comentario diría yo)
Hay muchas formas. Pero el spam solo te da mala imagen.
Realmente si queres subir puntos hacelo sin trampa además el único perjudicado a la larga serás vos. 😐
La verdad no conocia sobre este estilo de programacion, Python esta lleno de sorpresas.
Quise emular la implementacion en JS del estilo LBYL usando la librería pydash (se instala con un pip install pydash desde la consola), y el código terminó así:
# LBYL style
import pydash
def buscaPais(paises, pais): result = pydash.objects.find_key(paises, lambda p: p == pais)return result
print(f'LBYL style: {buscaPais(paises, "NombrePais")}')
Excelente!
Por favor si alguien me lo podría explicar de una mejor manera, leí los comentarios en los que trataban de explicarlo pero aún no me queda claro.
Lo que entendí es algo así maso menos:
++ - EAFP( pedir permiso antes que disculpas) ++
Analiza todas las opciones y luego si no la encuentra manda una clave de error, si no hay error arroja la respuesta.
++ - LBYL(revisa antes de saltar) ++
En primer lugar verifica si encuentra el valor pedido en la busqueda, ahí salta el error, pero si verifica que esta el valor buscado ahí pasa a la otra condicional y arroja el resultado.
Clayton:
Mi explicación en palabras simples, veamos si te resulta más sencillo.
EAFP --> hago lo que tengo que hacer, proceso lo que tenga que procesar, y si veo que hay un dato/valor/cálculo que genera excepción, entonces lo manejo
LBYL --> primero me aseguro que no pase algún dato/valor/cálculo que genere excepción, si es así manejo la excepción. Luego de eso hago lo que tengo que hacer, proceso lo que tenga que procesar.
En ambos casos, no hay obligatoriedad de usarlos, solamente son 'estilos' saludables para manejar excepciones.
Gracias @marisolcatari por la explicación! Yo también tenía la misma duda :D