Why is lambda expression necessary in this example? (Python) Why is lambda expression necessary in this example? (Python) tkinter tkinter

Why is lambda expression necessary in this example? (Python)


Like you guessed, when you use command = showinfo(name) you are asking python to immediately call showinfo(name), and then assign the result of that to the command attribute.

The command attribute must be given a reference to a function. lambda is a convenient way to create an anonymous function and return the reference, which gets assigned to the attribute. Inside that anonymous function you can call any other function you want, and that inner code isn't executed until the anonymous function is executed.

The functional purpose of lambda is to create a temporary, unnamed function that can be passed to other functions or stored as an attribute. It is a convenient way (but not the only way1) to create a wrapper around a callback that requires an argument.

1Another way to accomplish the same thing is with functools.partial. Another method would be to write your own decorator.


A callback is simply a function that you pass around to other functions so those functions can call it. showinfo(name) is not a callback because the function is called immediately before the Button is constructed and the return value of showinfo seems to be None (if a function doesn't return anything it returns None by default in Python).

showinfo by itself, could be a callback because it's a function, however the problem is that it requires a positional argument. In Python, positional arguments are required:

def f1(callback): callback()def f2(arg1): passf1(f2) # TypeError: f2() takes exactly 1 argument (0 given)

The way your code solves this is with a lambda expression that takes a default parameter that we define on-the-fly to be name. So what we are saying is, here is a function that by has a keyword argument arg that by default is set to name, when this function is called, call showinfo with that default argument:

btn = tkinter.Button(text = name, command=lambda arg=name: showinfo(arg))

But why do we need to use default arguments? Isn't that a complicated way of doing things? Yes, yes it is. You can simply do this instead:

btn = tkinter.Button(text = name, command=lambda: showinfo(name))

This is a lambda that takes no arguments and is a perfectly valid equivalent to what you're doing. This is because showinfo and name are part of the closure of the lambda you're creating, so they can be accessed by the lambda itself even after the lambda function has been passed to another function.

Yes, but it's necessary because each lambda function you pass in needs the value of name at the time that the lambda was created. Relying on a closure to keep the value of name won't do the trick, because the value of name changes on every iteration of the loop.