4

我正在使用 Tkinter 进行简单的琐事游戏。有几个按钮,每个答案一个,我想在单击一个时运行带有某些参数的 checkAnswer 函数。

如果我使用以下内容:

self.option1 = Button(frame, text="1842", command=self.checkAnswer(question=3, answer=2))

然后它将运行 checkAnswer 并使用它返回的内容(无)。

有没有一种简单的方法可以将参数存储在按钮构造函数中?

4

5 回答 5

15

这正是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))
于 2012-05-21T21:34:05.713 回答
2

您可以创建一个高阶函数来包装您的checkAnswer函数。这将允许您返回一个不需要任何参数的函数,因此可以用作回调。

例如:

def makeCheckAnswer(self, **kwargs)
    return lambda: self.checkAnswer(**kwargs)

这将使您的按钮初始化:

self.option1 = Button(frame, text="1842", command=self.makeCheckAnswer(question=3, answer=2))
于 2012-05-21T21:17:21.157 回答
1

到目前为止最简单的就是在适当的位置使用 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允许您错误输入函数参数并仅在单击按钮时获得异常的区别;)

此外,硬编码按钮代码中的问题/答案似乎不正确......

于 2012-05-21T22:28:50.647 回答
0

如果您有具有特定参数的函数(不依赖于类似的东西text.get()),您可以使用包装器,这将是执行此操作的最简单方法,而不是 lambda 函数。例如:

def option1wrapper():
    ClassName.checkAnswer(question=3,answer=2)
self.option1 = Button(frame, text="1842", command=option1wrapper)
于 2012-05-21T21:08:59.760 回答
0

只有你需要使用这样的 lambda 函数

self.option1 = lambda: Button(frame, text="1842", command=self.checkAnswer(question=3, answer=2))
于 2021-08-06T23:09:52.787 回答