[pyar] Problemita con lambda

Claudio Freire klaussfreire en gmail.com
Lun Ene 17 23:15:02 ART 2011


2011/1/17 Andrés Gattinoni <andresgattinoni en gmail.com>

>            for item in categoryList:
>                categories.addAction(item.name, lambda:
> self.set_category(item.id))
>            categories.addSeparator()
>
...

> Para poder pasarle el ID de la categoría al método set_category estoy
> usando lambda, con la idea de asignarle como callback del QAction un
> closure que contenga el ID de la categoría correspondiente.
>
> Lo que estoy viendo es que cuando corro el programa, la primera vez
> que defino una categoría para un item funciona bien. Pero cuando
> quiero categorizar un segundo ítem, me vuelve a pasar el mismo ID de
> categoría al método set_category.
>

Por lo que veo, el lambda ese tiene una única celda (variable libre), y no
es el id precisamente. Es el item.

Y no es "el item", sino "la variable item".

Notá la diferencia: "variable item". Para cuando se llama, la variable item
de todos los lambda que creaste... tiene le mismo valor. Pues es una
variable. Así que todos los lambdas usan el último item del for.

Este es un "problema" que me encontré seguido, y mi patrón preferido para
solucionarlo es:

for item in categoryList:
    categories.addAction(item.name, lambda item=item: self.set_category(
item.id))

¿qué hice?

Eliminé la variable libre, y la reemplacé por un parámetro (variable local)
con un valor por defecto. El valor por defecto se define al momento de crear
la función lambda, así que efectivamente cada lambda utiliza el item
correspondiente.

Veamos:

Como lo tenés:

>>> def f():
...    return [ (lambda : x) for x in xrange(10) ]
...
>>> print map(apply, f())
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
>>>

Como digo:

>>> def f():
...    return [ (lambda x=x:x) for x in xrange(10) ]
...
>>> print map(apply, f())
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20110117/4a991196/attachment.html>


More information about the pyar mailing list