[Tkinter-discuss] Problems with lambda functions in callbacks

mkieverpy at tlink.de mkieverpy at tlink.de
Fri Feb 16 17:37:42 CET 2007


Hello Dídac,

just to add an explanation, why your code doesn't work:

>from Tkinter import *
>
>root = Tk();
>
>def cb(x):
>    print x;
   
>for i in range(5):
>    b = Button(root,text=i,command=lambda:cb(i));

The part "lambda:cb(i)" is a function which gets evaluated
(called) when a button is clicked. It is evaluated
in the scope where it is defined. In this scope (the global scope)
the for-loop has finished running long ago.
Thus 'i' is always evaluated to '4' regardless which
button is pressed because this is the value of 'i'
after the end of the loop.

Stewart's code:
   b = Button(root,text=i,command=lambda i=i:cb(i));
This code works because it turns the loop variable 'i'
into a default value for the parameter 'i' of the lambda function.
And default values are evaluated when the function is defined,
i.e. while the loop is running.

>    b.pack();
>
>root.mainloop();

Hope this helps to demystify this behaviour,

Matthias Kievernagel
(mkiever/at/web/dot/de)


More information about the Tkinter-discuss mailing list