Welcome, guest | Sign In | My Account | Store | Cart

A utility class that makes writing callbacks more pleasant than using lambda. Especially using with Tkinter.

Python, 8 lines
1
2
3
4
5
6
7
8
class Command:
    def __init__(self, callback, *args, **kwargs):
        self.callback = callback
        self.args = args
        self.kwargs = kwargs

    def __call__(self):
        return apply(self.callback, self.args, self.kwargs)

(I remember seeing this utility class a while back, but don't remember who to attribute it to. Perhaps I saw this in Grayson's book.)

Writing callbacks that give customized arguments can look a little awkward with lambda, so this Command class gives an alternative syntax that's nicer. For example:

import Tkinter def hello(name): print "Hello", name root = Tk()

The lambda way of doing it:

Button(root, text="Guido", command=lambda name="Guido": hello(name)).pack()

Using the Command class:

Button(root, text="Guido", command=Command(hello, "Guido")).pack()

4 comments

Martin Sjogren 20 years, 3 months ago  # | flag

But what if the callback takes arguments? Your __call__ method would have to take args, *kwds arguments as well, and you'd have to merge your preset arguments and the ones given. Don't ask me how :-)

A "callback" that only supports empty argument lists isn't very useful!

Alex Martelli 20 years, 1 month ago  # | flag

tkinter often uses no args. typical tkinter callbacks have no args, so this recipe's quite useful for that need. more general curry solutions (applicable to all sort of callbacks &c) can be found in other recipes.

Rick Graves 16 years, 5 months ago  # | flag

source of utility function. This function is definitely in Grayson's "Python and Tkinter Programming", and is credited to a Python news group posting by Timothy R. Evans.

a 11 years, 7 months ago  # | flag

apply() is deprecated. apply(self.callback, self.args, self.kwargs) should be changed to self.callback(*self.args, **self.kwargs)