problem using lambdas for deferred callbacks
Fredrik Lundh
fredrik at pythonware.com
Sun Dec 10 11:07:34 EST 2006
edd at nunswithguns.net wrote:
> I was hoping that the following code would print "Hello, world!", one
> character per line. But instead it prints an exclamation mark for each
> character of the string. I'm sure it's no coincidence that the last
> value of c is '!', but beyond that I don't understand what's happening.
>
> # --- begin code ---
> def callback(arg):
> print arg
>
> funcs = []
> for c in 'Hello, world!':
> funcs.append(lambda: callback(c))
the "lambda" introduces a new function scope, and since the "c" variable
isn't defined in there, it's bound to the variable with the same name
from the outer scope. the problem here is that it's bound to the
*variable*, not the object, so *all* callbacks will use the same value.
there are several ways to bind to an object value instead; the easiest
in this case is to use a default argument value:
for c in 'Hello, world!':
funcs.append(lambda c=c: callback(c))
this turns the inner "c" variable to an argument that defaults to the
value of the outer "c" at the time the lambda was created.
</F>
More information about the Python-list
mailing list