I need a callback function that is almost exactly the same for a series of gui events. The function will behave slightly differently depending on which event has called it.
Python does uses references of course, but it does not matter in this context.
When you define a lambda (or a function, since this is the exact same behavior), it does not evaluate the lambda expression before runtime:
# defining that function is perfectly fine
def broken():
print undefined_var
broken() # but calling it will raise a NameError
Even more surprising than your lambda example:
i = 'bar'
def foo():
print i
foo() # bar
i = 'banana'
foo() # you would expect 'bar' here? well it prints 'banana'
In short, think dynamic: nothing is evaluated before interpretation, that's why your code uses the latest value of m.
When it looks for m in the lambda execution, m is taken from the topmost scope, which means that, as others pointed out; you can circumvent that problem by adding another scope:
def factory(x):
return lambda: callback(x)
for m in ('do', 're', 'mi'):
funcList.append(factory(m))
Here, when the lambda is called, it looks in the lambda' definition scope for a x. This x is a local variable defined in factory's body. Because of this, the value used on lambda execution will be the value that was passed as a parameter during the call to factory. And doremi!
As a note, I could have defined factory as factory(m) [replace x by m], the behavior is the same. I used a different name for clarity :)
You might find that Andrej Bauer got similar lambda problems. What's interesting on that blog is the comments, where you'll learn more about python closure :)