[pyar] Pedir perdón o pedir permiso (era: input function)

Diego Sarmentero diego.sarmentero en gmail.com
Mie Mar 7 13:53:48 ART 2012


El día 7 de marzo de 2012 13:47, fisa <fisadev en gmail.com> escribió:
> El día 7 de marzo de 2012 13:44, Facundo Batista
> <facundobatista en gmail.com> escribió:
>> 2012/3/7 fisa <fisadev en gmail.com>:
>>
>>> Try/except sirve para capturar excepciones, para manejarlas con
>>> "gracia", pero capturar una exception es un proceso mucho más caro que
>>> resolver antes el camino con un if. El try/except debería ser el
>>> "último recurso" para las cosas que no pudimos evitar por caminos
>>> normales.
>>
>> Not really.
>>
>> Esto que se está discutiendo acá generalmente se llama "pedir perdón o
>> pedir permiso" (cambié el subject del thread por eso), y ninguno de
>> los dos es el último recurso de nada.
>>
>> Hacer un try/except es "pedir perdón" (lo hacés, quizás te equivocás,
>> pedís perdón con el except). Hacer un if es "pedir permiso", primero
>> preguntás que onda y luego hacés o no hacés.
>>
>> ¿Dónde o cuando usar uno o el otro? Bueno, depende.
>>
>> La regla *general* es que si vos estás más o menos seguro que va a ir
>> todo bien, uses el try/except. Y si no tenés idea, que uses el if. Y
>> si no te importa, uses el que más lindo queda.
>>
>> Hay que tener en cuenta que hacer un try/except es muy muy barato si
>> va todo bien, pero si hay una excepción es caro. Y el if... bueno,
>> dependerá de cada expresión que se use para ese if.
>>
>> Sólo como un ejemplo, analicemos el caso del thread anterior.
>>
>> facundo en phenomenux:~$ timeit.py -s "a = '23'" "int(a)"
>> 1000000 loops, best of 3: 0.972 usec per loop
>>
>> facundo en phenomenux:~$ timeit.py -s "a = '23'" "
>> try:
>>  int(a)
>> except:
>>  pass
>> "
>> 1000000 loops, best of 3: 0.975 usec per loop
>>
>>
>> O sea, lo mismo. ¿Cuanto cuesta hacer el if?
>>
>> facundo en phenomenux:~$ timeit.py -s "a = '23'" "a.isdigit()"
>> 10000000 loops, best of 3: 0.165 usec per loop
>>
>>
>> O sea, un 18% de overhead, si todo va a ir bien.
>>
>>
>> facundo en phenomenux:~$ timeit.py -s "a = '23a'" "
>> try:
>>  int(a)
>> except:
>>  pass
>> "
>> 100000 loops, best of 3: 3.28 usec per loop
>>
>>
>> O sea, algunas veces más caro si el string era inválido.
>>
>>
>> Por supuesto, para el caso del ejemplo (tomar input del usuario) estas
>> diferencias de microsegundos no nos importan.
>>
>> Pero en otros casos sí, y la velocidad no es lo único a considerar...
>> saber si algo es un número entero, es fácil, con el isdigit(), y
>> quizás queda más elegante con el if. Pero si queremos saber si es un
>> número decimal? Ahí es más complicado, y quizás eso justifique el
>> poner un try/except alrededor de un float().
>>
>>
>> Otro caso típico, y repito, es sólo otro ejemplo, es el de usar un
>> diccionario de caché, ejemplo:
>>
>> def hace_algo(input):
>>    try:
>>        output = dict_como_cache[input]
>>    except KeyError:
>>        output = funcion_cara(input)
>>        dict_como_cache[input] = output
>>    return output
>>
>> En ese caso, nosotros esperamos que las cosas estén en el caché, y
>> está super optimizado para que si está allí, se devuelva el valor
>> rápido. Y si no está en el caché, el costo de tener la excepción es
>> despreciable contra el costo de aplicar la función que estamos
>> cacheando.
>>
>>
>> Para terminar, recalco que son sólo dos ejemplos, y que hay que
>> conocer y saber usar ambas "expresiones idiomáticas", y usarlas
>> donde/cuando corresponde.
>>
>> Lo que sí, seguro, ninguna de las dos "está mal".
>>
>> Saludos!
>>
>> PD: releyendo, veo que quedó como para poner una página en el wiki con esto, no?
>>
>> --
>> .    Facundo
>>
>> Blog: http://www.taniquetil.com.ar/plog/
>> PyAr: http://www.python.org/ar/
>> _______________________________________________
>> pyar mailing list pyar en python.org.ar
>> http://listas.python.org.ar/listinfo/pyar
>>
>> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>>
>> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de Argentina - http://www.usla.org.ar
>
> Buena explicación, me hizo cambiar un poco de opinión.
> Y sip, estaría bueno que vaya a la wiki.
>
> --
> fisa  -  Juan Pedro Fisanotti
> _______________________________________________
> pyar mailing list pyar en python.org.ar
> http://listas.python.org.ar/listinfo/pyar
>
> PyAr - Python Argentina - Sitio web: http://www.python.org.ar/
>
> La lista de PyAr esta Hosteada en USLA - Usuarios de Software Libre de Argentina - http://www.usla.org.ar


Un ejemplo que me parece bien claro de cuando pedir perdon, que pedir
permiso, es por ejemplo que construyas un iterator y no lo iteres con
un for por ejemplo onda:
l = [1,2,3]
iter = reversed(l)
item = iter.next()

y supone que lo estas iterando con un while, no tenes con el reverse
iterator como preguntar si el siguiente item es valido (o estoy muy
errado, pero len no sirve), entonces en ese caso usas la iteración
dentro de un try-except, total sabes que esa iteración solo va a
entrar en el try-except cuando la iteracion termine largando un
StopIterator (que no es exception, ni error realmente... a no ser que
no lo agarres :P), y por lo tanto es mas simple usar esa estructura
porque solo entraria una vez ahí, que seria al final.

My 2 cents... si sirve un poco....

-- 
Diego Sarmentero

Blog: http://diegosarmentero.com
Twitter: http://twitter.com/diegosarmentero



More information about the pyar mailing list