[Twisted-Python] lambdas and DeferredList
Andrew Bennetts
andrew-twisted at puzzling.org
Fri Aug 3 03:06:25 MDT 2007
gary jefferson wrote:
> I don't quite understand the behavior of lambdas in the following code:
>
[...]
> values = [(1, 'one'), (2, 'two'), (3, 'three')]
> for i, v in values:
> deferred = someDeferred(i)
> deferred.addCallback(onething, i, lambda: twothing(v))
> dlist.append(deferred)
> dl = defer.DeferredList(dlist)
> dl.addCallback(done)
[...]
>
> Which produces:
> onething: 1, result 1
> twothing: three
> onething: 2, result 2
> twothing: three
> onething: 3, result 3
> twothing: three
> all done
>
>
> Why does the call to twothing() (via a lambda and callableThing)
> always bind to 'three'? How do I change the code to get it to bind
> successively to 'one', 'two', and 'three'?
You don't need Twisted to see this:
>>> values = ['one', 'two', 'three']
>>> functions = []
>>> for value in values:
... functions.append(lambda: value)
...
>>> for func in functions: print func()
...
three
three
three
The simplest fix is use "lambda foo=foo: ...", to bind the value of the variable
as it was at the time the lambda statement is executed to a local variable in
that function. i.e.:
>>> values = ['one', 'two', 'three']
>>> functions = []
>>> for value in values:
... functions.append(lambda v=value: v)
...
>>> for func in functions: print func()
...
one
two
three
Refer to the Python documentation about scoping for more details.
-Andrew.
More information about the Twisted-Python
mailing list