我正在使用 Tkinter 进行简单的琐事游戏。有几个按钮,每个答案一个,我想在单击一个时运行带有某些参数的 checkAnswer 函数。
如果我使用以下内容:
self.option1 = Button(frame, text="1842", command=self.checkAnswer(question=3, answer=2))
然后它将运行 checkAnswer 并使用它返回的内容(无)。
有没有一种简单的方法可以将参数存储在按钮构造函数中?
这正是functools.partial()
设计的目的:
>>> import functools
>>> print_with_hello = functools.partial(print, "Hello")
>>> print_with_hello("World")
Hello World
>>> print_with_hello()
Hello
partial()
返回一个新函数,其行为与旧函数一样,但您传入的任何参数都已填充,因此在您的情况下:
import functools
...
self.option1 = Button(frame, text="1842", command=functools.partial(self.checkAnswer, question=3, answer=2))
您可以创建一个高阶函数来包装您的checkAnswer
函数。这将允许您返回一个不需要任何参数的函数,因此可以用作回调。
例如:
def makeCheckAnswer(self, **kwargs)
return lambda: self.checkAnswer(**kwargs)
这将使您的按钮初始化:
self.option1 = Button(frame, text="1842", command=self.makeCheckAnswer(question=3, answer=2))
到目前为止最简单的就是在适当的位置使用 lambda
self.option1 = Button(frame, text="1842",
command=lambda: self.checkAnswer(question=3, answer=2))
虽然,在类似但更复杂的情况下,您确实应该使用函数工厂,例如
def answerCheckerFactory(self, question, answer):
def checker():
return self.checkAnswer(question, answer)
return checker
...
self.option1 = Button(frame, text="1842",
command=self.answerCheckerFactory(question=3, answer=2))
因为它将确保您传递正确的参数(quetsion
例如,不是(原文如此));请注意functools.partial
允许您错误输入函数参数并仅在单击按钮时获得异常的区别;)
此外,硬编码按钮代码中的问题/答案似乎不正确......
如果您有具有特定参数的函数(不依赖于类似的东西text.get()
),您可以使用包装器,这将是执行此操作的最简单方法,而不是 lambda 函数。例如:
def option1wrapper():
ClassName.checkAnswer(question=3,answer=2)
self.option1 = Button(frame, text="1842", command=option1wrapper)
只有你需要使用这样的 lambda 函数
self.option1 = lambda: Button(frame, text="1842", command=self.checkAnswer(question=3, answer=2))