Diez B. Roggisch wrote:
...
for i in xrange(4):
thread = threading.Thread(target=lambda : foo(i))
thread.start()
... So it appears that the curried lambda passed as target is
somehow a reference equal for all four invocations....
This is why the "curry" recipe dances more jig than you have.
the lambda-expression that you've passed in did not do any
value-capture. The smallest fix is: ...
for i in xrange(4):
thread = threading.Thread(target=lambda v=i: foo(v))
thread.start()
...
With curry from the Python Cookbook (or as below), I'd write: ...
for i in xrange(4):
thread = threading.Thread(target=curry(foo, i))
thread.start()
...
The problem is that your lambda expression looks up "i" at function
evaluation time (when target is called), not when you assign the
target function for the thread.
-Scott David Daniels
Sc***********@Acm.Org
=============================
for 2.2 I define curry as:
from __future__ import nested_scopes
def curry(*_args, **_kwargs):
"""curry(f,<args>)(<more>) == f(<args>, <more>) (roughly).
keyword args in the curry call can be overridden by keyword args
in the later call; curry can be used to change defaults.
"""
def result(*__args, **__kwargs):
if _kwargs and __kwargs:
kwargs = _kwargs.copy()
kwargs.update(__kwargs)
else:
kwargs = _kwargs or __kwargs
return _args[0](*(_args[1:]+__args), **kwargs)
return result