[pyar] Problemita con lambda

Andrés Gattinoni andresgattinoni en gmail.com
Lun Ene 17 23:25:08 ART 2011


2011/1/17 Claudio Freire <klaussfreire en gmail.com>:
> 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]
>>>>

Muchísimas gracias por tu respuesta tan completa. Lo hice como
sugeriste y salió andando.

Saludos,

A



More information about the pyar mailing list