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