button1 = tkinter.Button(frame, text="Say hi", command=print)
button2 = tkinter.Button(frame, text="foo", command=print)
button3 = tkinter.Butto开发者_StackOverflow社区n(frame, text="bar", command=print)
You've probably spotted the hole in my program: print
can't specify arguments. This renders the whole thing useless and faulty. Obviously, having something like
command=print("foo")
will call that function when the object is actually instantiated and make command
the return value (if any) of that function call. (Not what I want)
So, how can I specify arguments in the above mentioned scenario, and avoid having to define seperate command
functions for each of the buttons?
If you have at least python 2.6 (which I'm guessing you are since you use print in a function position) you can use functools.partial
. It takes a function and any arguments to supply and returns a callable that will call the underlying function and add on any arguments passed to the final call. For example:
>>> from functools import partial
>>> def add(x,y): return x+y
>>> add2 = partial(add,2)
>>> add3 = partial(add,3)
>>> add2(3)
5
>>> add3(5)
8
Your example could be done as
from functools import partial
button1 = tkinter.Button(frame, text="Say hi", command=partial(print,"hi"))
button2 = tkinter.Button(frame, text="foo", command=partial(print,"foo"))
button3 = tkinter.Button(frame, text="bar", command=partial(print,"bar"))
If you don't have 2.6, you can implement partial as:
def partial(fun, *args, **kwargs):
def merge(d1,d2):
r = dict(d1)
r.update(d2)
return r
return lambda *a,**kw: fun(*(args+a),**(merge(kwargs,kw)))
A simple solution is to use lambda, which lets you create anonymous functions.
button1 = tkinter.Button(frame, text="Say hi", command=lambda: print("Say hi")
button2 = tkinter.Button(frame, text="foo", command=lambda: print("foo"))
button3 = tkinter.Button(frame, text="bar", command=lambda: print("bar"))
Another choice is to use functools.partial, which is explained a bit in this answer: https://stackoverflow.com/a/2297423/7432
精彩评论