[Tutor] Button command arguments: Using class to wrap function call versus using lambda in tkinter
boB Stepp
robertvstepp at gmail.com
Sun Apr 23 01:02:48 EDT 2017
Phil's recent postings have motivated me to try studying tkinter more
systematically starting today, so I have been looking over available
web resources. Playing around with the code in one such resource, I
was looking at a section entitled "Arguments to Callbacks" towards the
bottom of the page at
http://userpages.umbc.edu/~dhood2/courses/cmsc433/spring2012/?section=Notes&topic=Python¬es=92
they have the code snippet:
==========================================================================
import Tkinter
# command class to wrap function call with args
# a.k.a. "currying"
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)
def callback(arg):
print "You called callback with the following arg: %s" % arg
root = Tkinter.Tk()
Tkinter.Button(root, text="Foo", command=Command(callback, 'Foo')).pack()
Tkinter.Button(root, text="Bar", command=Command(callback, 'Bar')).pack()
Tkinter.Button(root, text="Baz", command=Command(callback, 'Baz')).pack()
root.mainloop()
==========================================================================
This is Python 2 code, so I endeavored to convert it to Python 3. I
came up with:
==========================================================================
#!/usr/bin/env python3
import tkinter as tk
# Command class to wrap function call with args
# A.K.A. "currying"
class Command:
def __init__(self, callback, *args, **kwargs):
self.callback = callback
self.args = args
self.kwargs = kwargs
def __call__(self):
return self.callback(*self.args, **self.kwargs)
def callback(arg):
print('You called callback with the following arg: %s' % arg)
root = tk.Tk()
tk.Button(root, text='Foo', command=Command(callback, 'Foo')).pack()
tk.Button(root, text='Bar', command=Command(callback, 'Bar')).pack()
tk.Button(root, text='Baz', command=Command(callback, 'Baz')).pack()
root.mainloop()
==========================================================================
This seems to work fine, and got me to wondering about using lambda
instead of this class wrapper approach, which gave me:
==========================================================================
import tkinter as tk
def callback(arg):
print('You called callback with the following arg: %s' % arg)
root = tk.Tk()
tk.Button(root, text='Foo', command=lambda arg='Foo': callback(arg)).pack()
tk.Button(root, text='Bar', command=lambda arg='Bar': callback(arg)).pack()
tk.Button(root, text='Baz', command=lambda arg='Baz': callback(arg)).pack()
root.mainloop()
==========================================================================
And this also works well. Seeing as this approach has fewer lines of
code and reads clearly, what advantages would the class wrapper
approach have? The only thing that is occurring to me in my current
sleepy state is that the class wrapper is much more flexible with
handling varying passed arguments. Are there other considerations I
should be aware of?
As usual, many thanks in advance!
Cheers!
--
boB
More information about the Tutor
mailing list