首页 > 解决方案 > Python:不明白为什么在 GUI“command=”中需要 lambda 来调用函数

问题描述

在学习Python的过程中。我了解 lambda 的使用,这是一个示例和链接(供其他人使用)。

为什么 Python lambdas 有用?

mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9])

将 [3, 6, 9] 分配给 mult3。


这是我在本书的测验中需要做的代码:

import tkinter

def counter(text):
    """Add 1 every time the button is pressed"""

    count = int(text.get())
    text.set(count + 1)


window = tkinter.Tk()
frame = tkinter.Frame(window)
frame.pack()

var = tkinter.IntVar()
var.set(0)

button = tkinter.Button(window, textvariable=var, command=lambda: counter(var))
button.pack()

tkinter.mainloop()

那是经过验证的解决方案。除了变量按钮中的代码外,我想出的是相同的。这是我的台词:

button = tkinter.Button(window, textvariable=var, command=counter(var))

缺少 lambda 会阻止计数器工作。我不明白为什么需要 lambda?因为我只是调用我创建的函数,所以我不需要新的未命名函数..?

在此先感谢您的时间 :)

标签: pythonpython-3.xuser-interfacetkinter

解决方案


这里发生了几件事。首先,当 python 编译command=counter(var)时,它会调用函数并将其结果分配给command. 你打电话counter了,你的回电现在是None,这显然不是你想要的。

您不能只做command=counter简单地使counter函数在回调中使用的操作,因为 API 没有办法为回调包含参数。所以你也是

command=lambda:counter(var)

这会分配一个不带参数的匿名函数,command就像 API 想要的那样。lambdavar在包含范围内包含对它的引用,然后用于调用counter. 这就是您为真正想要的目标回调创建参数的方式。

这个参考有点奇怪。它是对包含范围内的插槽的引用,而不是在分配时var碰巧在其中的对象。var如果var在进行回调之前进行更改(或者包含范围消失,就像函数返回时局部变量消失一样),则使用该新对象。所以,把你的代码放在一个函数中,这样你就不会让自己发疯!


推荐阅读