Excepciones y control de flujo

29/31

Lectura

Excepciones como control de flujo

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".

Aportes 112

Preguntas 3

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

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.

print('BUSCADOR DE CAPITALES')

pais  = input('\nEscribe el pais al que desees conocer su capital: ')

def busca_pais(paises, pais):
    try:
        return paises[pais]
    except KeyError:
        return print('\n \nEl pais que buscas, no se encuentra en la base de datos')

paises = {
        'Colombia': 'Bogota',
        'Uruguay': 'Montevideo',
        'Espa帽a': 'Madrid',
        'Canada': 'Ottawa',
        'Argentina': 'Buenos Aires',
        'Australia': 'Canberra',
        'Bolivia': 'Sucre',
        'Brasil': 'Brasilia',
        'Chile': 'Santiago',
        'Venezuela': 'Caracas',
        'Costa Rica': 'San Jose',
        'Cuba': 'La Habana',
        'Ecuador': 'Quito',
        'Egipto': 'El Cairo',
        'Francia': 'Paris',
        'Filipinas': 'Manilla',
        'India': 'Nueva Delhi',
        'Indonesia': 'Yakarta',
        'Italia': 'Roma',
        'Libano': 'Beirut',
         }

print(busca_pais(paises, pais))

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:
        return print(diccionario[llave])
    except KeyError as e:
        print(e)
        return (f'{llave} no se encontro en el diccionario')

def actualizar_genero_diccionario(diccionario,llave,valor):
    diccionario.update({llave:valor})
    return print(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)
        return print(f'Hola {diccionario.values()}')
    except NameError as e:
        print(e)
        return print(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)
        return manipular_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)
        return manipular_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)
        return manipular_dict(diccionario)
    else:
            print('No se encontr贸 n煤mero en el menu')
            return manipular_dict(diccionario)
        

x = manipular_dict(anime)        

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.

EAFP:

try:
       x = my_dict["key"]
except KeyError:
       # handle missing key

LBYL:

if "key" in my_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.

Script completo EAFP en Python 馃悕 馃槂

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:
        return None

def run():
    paises = {
        'Mexico':1,
        'Argentina':2,
        'Colombia':3
    }

    pais = input('Ingrese su pais: ')

    print(busca_pais(paises, pais))


if __name__ == '__main__':
    run()

Como dice la info, el estilo EAFP es m谩s pythonico, sin embargo, para efectos de ilustraci贸n creo que esto podr铆a servir

EAFP

try:
        return paises[pais]
    except KeyError:
        return None

LBYL

if pais not in paises.keys():
        return None
return paises[pais]

En LBYL, en la funci贸n built-in de los diccionarios llamada 鈥渒eys鈥 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.

Pythonico!

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

Python es muy elegante, se tenia que decir y se dijo.

pythonico 馃槂

Me gusto el uso de la palabra 鈥減ythonico鈥

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禄_

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.

Prefiero python!!

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")}')

Me parece mucho mas f谩cil el estilo EAFP, punto para Python 馃槀馃槀

No lo entend铆 muy bien, alguien me lo explica?

jajajaja es m谩s f谩cil pedir perd贸n que permiso

Pythonico jejejejeje ahora somos Pythonicos

Excelente!!

No entend铆 muy bien esto. Alguien recomienda alguna otra fuente? Gracias.


Encontr茅 este ejemplo que muestra como funciona el **EAFP** 

< 
# Python

# En lugar de preguntar por algo, se intentar hacerlo. 
# Si funciona, muy bien! Sino, se captura el error y se gestiona de la mejor manera

try:
    f = open(my_file)     # Abramos un archivo que no existe 

except NameError as e:                  #  Como no existe, va  a haber un error

    print("name is not defined")    #  Aqui se gestiona el error haciendolo explicito
						    # El programa no colapsa
    with f:
        print(f.read()) 
>

Un poco complicado de entender, espero me quede mas claro a medida que avance en el curso.

nombre_pais = input(f'Ingrese el nombre de un pa铆s de LATAM: ')
def busca_paises (paises, pais):
#Diccionario de pa铆ses con el m茅todo EAFP 
    try:
        return paises[pais]
    except KeyError:
        return f'Pa铆s no se encuentra en la lista'
gentilicio = {
    'Colombia': 'Colombianos',
    'Chile':'Chilenos',
    'Argentina':'Argentos',
    'Brasil':'Brasileiros',
    'Venezuela':'Venezolanos'
}
print(busca_paises(gentilicio,nombre_pais))```

Me puede corregir se supone que lo que quiere decir es que si un paises no tiene la lave pais va a aparecer ese c贸digo?

Por eso me encanta python porque las excepciones y errores son computadas de una manera mas humana

Me gusto mucho la frase pythonica, easier to ask for forgiveness than permission, es m谩s f谩cil pedir perd贸n que permiso

La verdad no conocia sobre este estilo de programacion, Python esta lleno de sorpresas.

Me parece una muy buena mentalidad para programar.

Bien ejemplificados los principios, excelente.

**Principio EAFP **

  • Easier to ask for forgiveness than permission (es mas facil pedir perdon que permiso)
  • Se ejecuta el codigo y solo en caso de lanzarse un error, se captura la excepcion y la maneja
  • Muy utilizado en Python

Python se me ha hecho bastante sencillo, muchas gracias.

def busca_pais(country, pais):
    """
    paises es un diccionario. pais es la llave.
    codigo con el principio EAFP.
    """
    try:
        return paises[pais]

    except KeyError:
          returnNone

paises = {'Espa帽a': 'Espa帽a',  'Ecuador':'Ecuador','Francia':'Francia','Colombia':'Colombia','Rusia':'Rusia','Peru':'Peru'}       
pais = 'Francia'
print(busca_pais(paises, pais)) 

pyhton esta como facil

Genial muy 鈥楶ythonico鈥 todo.

Es m谩s sencillo entender el c贸digo de python. Gracias por la informaci贸n.

Por lo que entiendo la diferencia es que normalmente en python, se escriben primero las funcionalidades que queremos ejecutar y las probamos, despu茅s manejamos la excepci贸n.
En otros lenguajes es preferible primero ejecutar la excepci贸n y despu茅s ejecutar lo que queremos hacer.

En la parte que pone 鈥淧ais es un diccionario de paises.鈥, se refiere a que pais es una Key del diccionario paises?

def busca_pais(paises, pais):
    """
    Pais es un diccionario de paises.
    Codigo con el principio EAFP.
    """
    
    try:
        return paises[pais]
    except KeyError:
        return None```

Me revienta un poco la cabeza eso del 鈥減ythonistic way鈥 de hacer las cosas, pero esta es una buena implementaci贸n 馃槂

Gracias por la explicacion.

Amigos, encontre este articulo que espero que les sirva.
https://tutorial.recursospython.com/excepciones/

Vengo de Javascript y el manejo de errores en Python es lo que mas me ha gustado del lenguaje

Hola compa帽eros, saludos! Tuve unas cuantas dudas con este tema de 鈥渆xcepciones y manejo de excepciones鈥 la verdad no los entend铆 muy bien.
Alg煤n consejo que me puedan dar o explicaci贸n? 隆Agradecido!

Aqu铆 encontr茅 una comparaci贸n de desempe帽o entre los dos enfoques, por si te est谩s preguntando cu谩l es m谩s r谩pido y en qu茅 casos:

https://gist.github.com/cdgriffith/fa48d9b7032f848ddd5c37c3df35dbb7

PD: para ejecutarlo necesitas instalar 鈥渞eusables鈥 (ejecuta en la terminal):

pip install reusables

Principio LBYL

  • Look before you leap, revisa antes de saltar
  • El codigo verifica las precondiciones antes de realiar las llamadas
  • Usual en otros lenguajes de programacion aunque tambien se usa en python

鈥淓s m谩s f谩cil pedir perd贸n que permiso鈥, lo que me dice mi jefe cuando toca reiniciar los servidores en caliente.

Excelente!

Importante saber los conceptos de excepciones, con esto ya es m谩s f谩cil seguir aprendiendo otros lenguajes de programaci贸n.

Excelente curso. He aprendido much铆simo. Muchas gracias.

Notas 馃搾

鉁忥笍 Manejo de excepciones

  • Son muy comunes en la programaci贸n. No tienen nada de excepcional.
  • Las excepciones de python normalmente se relacionan con errores de sem谩ntica
  • Se pueden crear excepciones propias
  • Cuando una excepci贸n no se maneja (unhandled exception), el programa termina en error.
  • Las excepciones de manejan con los keywords: try, except, finally.
  • Se pueden utilizar tambi茅n para ramificar programas.
  • No deben manejarse de manera silenciosa
  • Para aventar tu propia excepci贸n utiliza el keyword raise.

鉁忥笍 Excepciones comunes (aporte de otro compa帽ero):

ImportError :

una importaci贸n falla;

IndexError :

una lista se indexa con un n煤mero fuera de rango;

NameError :

se usa una variable desconocida ;

SyntaxError :

el c贸digo no se puede analizar correctamente

TypeError :

se llama a una funci贸n en un valor de un tipo inapropiado;

ValueError :

se llama a una funci贸n en un valor del tipo correcto, pero con un valor inapropiado

鉁忥笍 Excepciones y control de flujo

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) es un estilo de programaci贸n com煤n en Python en el cual se asumen llaves, 铆ndices o atributos son 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.

EAFP

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

LBYL

/**
* 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.

def buscar_capital(base_paises, pais) :
    try :
        return base_paises[pais]
    except KeyError as e:
        return {k:v for k,v in base_paises.items()}

def run() :
    base_paises = {
        'Per煤' : 'Lima',
        'Colombia': 'Bogota',
        'Argentina' : 'Buenos Aires',
        'Bolivia' : 'La Paz',
        'Paraguay' : 'Asuncion',
        'Venezuela' : 'Caracas',
        'Uruguay' : 'Montevideo',
        'Brasil' : 'Brasilia',
        'Chile' : 'Santiago',
        'Ecuador' : 'Quito'
    }

    pais =  input('Buscar capital de pais: ')
    print(buscar_capital(base_paises, pais))

if __name__ == '__main__':
    run()

Nuevo Adjetivo aprendido: 鈥淧ythonico鈥 馃槂

Me identifico mucho m谩s con el principio LBYL, y el principio EAFP lo uso para casos en los que se que puede fallar, como por ejemplo una conexi贸n a una BD.

El principio EAFP es un estilo de programaci贸n com煤n en Python en el cual se asumen

def busca_pais(paises, pais):
    &quot;&quot;&quot;
    Paises es un diccionario. Pais es la llave.
    Codigo con el principio EAFP.
    &quot;&quot;&quot;
    
    try:
        return paises[pais]
    except KeyError:
        return None

traducido a c贸digo seria algo asi:


en consola:
![](

Este video me ayudo a reforzar el tema de la lectura, espero les sea util:

https://www.youtube.com/watch?v=YMx645JNBxk

La verdad es que Python tiene un estilo de programacion muy elegante y lo reconozco, pero no se porque me gusta mucho mas JS jaja
Tendra que ver que mis inicios en la programacion fue con C# y JavaScript de algun modo se apega un poquito mas a 茅l.

Excelentes notas sobra el manejo de excepciones

Hey este es mi c贸digo:

comidas={
    'burger':10,
    'salad':9,
    'mayo':8,
    'fish':7,
    'bread':6,

}

comida=input('Escriba la comida que desea para saber su precio ')

def busComida(comidas,comida):
    try:
        return print(comidas[comida])
    except KeyError:
        return print('No existe en el menu')

busComida(comidas, comida)

aporte para puntos

pythonicos!!

Muy buena informaci贸n!

Excelente!

Simplicidad + elegancia = python

Excelente, cada vez sorprende lo que logra simplificar python a la vez su m茅todo de volver algo sencillo en algo brutal.

Wow!!
De hecho una de las ventajas de Python 馃槂

Genial hoy acabo de aprender algo nuevo, por cierto el EAFP de python, me parece m谩s limpio que el LBYL de javascript.

Esencial entender el manejo de las excepciones para manejo de grupos de trabajo en programaci贸n.

Yo soy mas de LBYL pero tendr茅 que volverme m谩s atrevido con python

buena info, excelente

easier to ask for forgiveness than permission

pythonico 馃槅

Hay alguna raz贸n por la que en python no se utilice mas el m茅todo LBYL? Ya que he le铆do que utilizar las excepciones como manejo de flujo no es una buena practica de programaci贸n.

Desconoc铆a el principio EAFP y lo usaba todo el tiempo en RPA 馃ぃ

In Python, EAFP over LBYL!

Me encantan los nombre jajaja

Buena informaci贸n:

EAFP (easier to ask for forgiveness than permission, es m谩s f谩cil pedir perd贸n que permiso, por sus siglas en ingl茅s).
LBYL (look before you leap, revisa antes de saltar)

De entrada no entend铆 muy bien, pero s茅 que luego quiz谩s si sea m谩s claro.

El principio: LBYL (look before you leap, revisa antes de saltar) es muy muy comun y util en APIs en donde necesitamos decirle a quien consume el servicio que fu茅 lo que estuvo mal, lo que lanz贸 error o lo que envi贸 mal.

Excelente info, me gusta el Principio EAFP!!

Muy buena frase: 鈥淓s m谩s f谩cil pedir perd贸n que permiso鈥

Me surge una inquietud 驴Qu茅 ventajas a nivel de flujo de proceso y/o recursos de m谩quina brinda cada estilo? Tanto el ESFP como el LBYL?

Como podria ejecutar este ejemplo , lo trate de hacer de esta manera y no fue posible.

paises = [
    {'paises':'colombia'},
    {'paises':'peru'}
]
def busca_pais(country, pais):
    """ 
    Paises es un diccionario. Pais es la llave.
    Codigo con el principio EAFP.
    """

    try:
        return paises[pais]
    country = (paises[colombia])    
    except KeyError:
        return None```

Algun experto "Pythonico" que me pueda ayudar.

Entendido!

No entend铆. Por qu茅 este tipo de explicaciones no tienen video? Siento muy flojo el curso.


def inputVal():
    start =True
    while start==True:
        
        try:
            x=int(input())
            start=False
            return x            
        except ValueError:
            
            print('Ingrese un numero')
start =True
desicion=0
num1=0
while start==True:
    print('Escribe un numero')
    num=inputVal()
   
    num1+= num
    print('Desea sumar mas 1)si 2)No')
    desicion=inputVal()
    if desicion==1:
        start=True
    else:
        start=False
        print(f'la suma total esn{um1}')

Me parece que este concoimiento es fundamental a lo largo de la carrera de programacion. Muchas gracias

Muy importante conocer los dos tipos de formas de manejar las excepciones EAFP y LBYL, ademas tener en cuenta que EAFP es m谩s usado en Python.

En el caso de JavaScript tambi茅n se puede hacer un EAFP? o el lenguaje no lo permite?

def busca_pais(paises, pais):
    try:
        return paises[pais]
    except KeyError:
        return None```
def busca_pais(paises, pais):
    """
    Paises es un diccionario. Pais es la llave.
    Codigo con el principio EAFP.

    """
    error = "El dato ingesado no existe"
    try:
        return paises[pais]
    except KeyError:
        return error

paises = {
    'Venezuela': 'Caracas',
    'Colombia': 'Bogota',
    'Argentina': 'Cordova',
    'Canada': 'Ottawa'
}

if __name__ == '__main__':
    print(busca_pais(paises, 'Venezuela'))
    print(busca_pais(paises, 'Colombia'))
    print(busca_pais(paises, 'Italia'))

ta raro

Entendido

Las explicaciones de David cada vez me sorprenden m谩s! Sos un GENIO!

Entonces otro tipo de LBYL en Python podr铆a ser el statement:

madres.get('Gaia')

Cuando madres es un diccionario, y una Key llamada 鈥楪aia鈥 no es encontrada, ya que no ejecuta como error al suceder.