当我偶然发现this用户提交的解决方案(对其他人的问题)时,我正在搜索StackOverflow以解决我的问题:
appsMenu.add_command(label=app, command=openApp(Apps[app]))
调用函数的命令参数需要包含在
lambda
中,以防止它们被立即调用。另外,for循环中绑定的命令需要循环变量作为默认参数,以便每次都绑定正确的值。appsMenu.add_command(label=app, command=lambda app=app: openApp(Apps[app]))
正如您所看到的,用户写了lambda app=app
,为了爱我,我无法弄清楚原因。它做了什么?
答案 0 :(得分:1)
lambda
表达式用于定义单行(匿名)函数。因此,写作
f = lambda x: 2*x
(或多或少)等同于
def f(x):
return 2*x
此外,对于普通函数,也可以在lambda
函数中使用默认参数。因此
k = 2
f = lambda x=k: 2*x
可以作为f()
调用,其中x
将是k
的值,即2
或f(3)
x = 3
。现在,更奇怪的是,由于lambda
函数有自己的名称空间,因此可以将k
与x
交换为
x = 2
f = lambda x=x: 2*x
这意味着如果没有设置其他参数,则f()
的默认值将是(外部)x
值(即2
)。
因此,表达式
lambda app=app: openApp(Apps[app])
是一个函数(未命名),它使用一个参数app
和(外部)变量app
的默认值。当被调用时,它将执行指令openApp(Apps[app])
,其中Apps
是一个全局(外部)对象。
现在,我们为什么要这样做,而不是在调用command=openApp(Apps[app])
时写.add_command()
?原因是我们希望命令不是在定义命令时执行,即在调用.add_command()
时,而是在稍后的时间,即在选择菜单项时执行。
因此,为了遵循执行,我们包装在函数中执行openApp(Apps[app])
。选择菜单项后,将执行此功能。因此,我们将调用openApp
,而不是正确现在(在我们想要添加命令的时候),否则就是这种情况。
现在,由于调用lambda
函数时没有参数,因此它将使用其默认参数(外部)app
作为(内部)app
。这使得整个参数有点多余,因为外部变量可以在lambda
表达式中直接访问。因此,可以将表达式简化为lambda: openApp(Apps[app])
,即没有参数,使得整行
appsMenu.add_command(label=app, command=lambda: openApp(Apps[app]))
对我来说,这看起来有点简单,是我写它的方式,但从概念上讲,这与默认参数的代码没有区别。