Here is a simple example showing a problem that I don't understand
callbacks = [lambda : 1, lambda : 2]
for i, c in enumerate(callbacks):
if i == 0:
cb1 = c
cb2 = lambda : c()
print(cb1()) # print 1
print(cb2()) # print 2
It seems that in cb1, I'm correctly able to copy the "correct" callback, ie the one I'm refering to in the loop iteration However in cb2, even though I'm defining cb2 at a time when c refers to the 1st callback, it's updated afterwards to refer to the second callback
Can someone please shed some light on whatis going on ? this is pretty disconcerting
Is it possible that I write a lambda for cb2 and still refer to the first callback ?
CodePudding user response:
This is expected behavior. To see why, consider the following example:
x = 1
def d():
return x
d() # returns 1
x = 2
d() # now returns 2
In the above example, the function d returns whatever value is assigned to the variable x at the time of execution. Variables in an enclosing scope are not copied in a function body, but referenced. The same is true if the variable holds a function value. Remember, functions are just values in Python. The behavior doesn't change just because you're using lambda syntax to define your functions.
CodePudding user response:
The lambda is evaluated on runtime, when c
already changed.
Try this instead:
cb2 = lambda c=c: c()
Using a default value, you can fixate a certain local variable.