使用 Tkinter 按钮了解 Python Lambda 行为
Understanding Python Lambda behavior with Tkinter Button
我想了解按钮如何使用 lambda 工作。
我有以下 Python 代码:
from tkinter import *
def comando_click(mensagem):
print(mensagem)
menu_inicial = Tk()
menu_inicial.geometry("500x250+200+200")
botao = Button(menu_inicial, text = "Executar", command=comando_click("Nova_Mensagem"))
botao.pack()
menu_inicial.mainloop()
但是当我点击它时我的按钮不起作用,当我 运行 代码时它只在控制台中显示一次打印,我在问题中添加了一些打印:
Problem Picture one
好吧,当我在按钮中使用 Lambda 函数时,它似乎起作用了,我真的很想知道为什么。
Lambda working button Picture one
我刚刚向按钮添加了 lambda :
botao = Button(menu_inicial, text = "Executar", command=lambda:comando_click("Nova_Mensagem"))
Lambda working button Picture two
为什么对 lambda 有效?
如果没有 lambda,它也不应该工作,因为 lambda 基本上是一个匿名函数?
我非常想知道它为什么起作用,谢谢大家的帮助:)
编辑:谢谢你们,现在我终于明白发生了什么以及Python是如何工作的。非常感谢大家 :D
在此代码中:
command=comando_click("Nova_Mensagem")
您调用了 comando_click
函数一次,并将结果 (None
) 赋给了 command
参数。调用 command
时什么也不会发生(实际上你应该得到一个 TypeError
异常,因为 None
不可调用)。
在此代码中:
command=lambda:comando_click("Nova_Mensagem")
您实际上还没有调用 comando_click
-- 您创建了一个新函数(使用 lambda
),该函数将在调用时依次调用 comando_click
。每次单击按钮时,都会调用您的新函数。
如果 lambda
令人困惑,您可以像这样使用 def
做完全相同的事情:
def button_command():
comando_click("Nova_Mensagem")
...
command=button_command # no ()! we don't want to actually call it yet!
当您想创建一个不需要名称的小型一次性函数(例如,您想要创建一个函数调用带有特定参数的另一个函数,就像您在此处所做的那样。
问题是 comando_click("Nova_Mensagem")
您正在执行函数。所以命令=None.
在第二种情况下 lambda:comando_click("Nova_Mensagem")
返回一个内部调用 comando_click("Nova_Mensagem")
.
的 lambda
修复:只需输入 command=comando_click
.
如果你想用参数个性化 lambda,你可以这样写:
def handler(args):
def custom_handler():
print(args)
return custom_handler
botao = Button(menu_inicial, text = "Executar", command=handler("my custom string"))
当你使用()
和一个函数名(func(args)
)时,那么它立即calling/invoking函数而python正在执行该行,你不想要那个。您只想在单击按钮时调用该函数。 tkinter
将在内部为您调用该函数,您只需提供函数名称即可。
为什么要用lambda
?把它看成一个函数就是returns另一个函数,你的代码可以加长为:
func = lambda: comando_click("Nova_Mensagem")
botao = Button(menu_inicial, text = "Executar", command=func)
func
是函数名,如果你想调用它,你会说func()
。当你说 command=comando_click("Nova_Mensagem")
然后 command
有 command click
返回的值(因为你用 ()
调用函数),这是 None
如果我' m没有错,如果给定的值为None
,则不会被tkinter
调用。因此,由于 ()
,您的函数仅执行一次,并且作为调用该函数的结果,您在事件循环开始处理事件之前分配了函数调用 (None
) 的值。
其他一些方法:
- 使用
partial
来自 functools
:
from functools import partial
botao = Button(.....,command=partial(comando_click,"Nova_Mensagem"))
- 使用助手函数:
def helper(args):
def comando_click():
print(args)
return comando_click
botao = Button(...., command=helper("Nova_Mensagem"))
IMO,lambda
s 是继续调用带有参数的函数的最简单方法。
我想了解按钮如何使用 lambda 工作。 我有以下 Python 代码:
from tkinter import *
def comando_click(mensagem):
print(mensagem)
menu_inicial = Tk()
menu_inicial.geometry("500x250+200+200")
botao = Button(menu_inicial, text = "Executar", command=comando_click("Nova_Mensagem"))
botao.pack()
menu_inicial.mainloop()
但是当我点击它时我的按钮不起作用,当我 运行 代码时它只在控制台中显示一次打印,我在问题中添加了一些打印:
Problem Picture one
好吧,当我在按钮中使用 Lambda 函数时,它似乎起作用了,我真的很想知道为什么。
Lambda working button Picture one
我刚刚向按钮添加了 lambda :
botao = Button(menu_inicial, text = "Executar", command=lambda:comando_click("Nova_Mensagem"))
Lambda working button Picture two
为什么对 lambda 有效? 如果没有 lambda,它也不应该工作,因为 lambda 基本上是一个匿名函数?
我非常想知道它为什么起作用,谢谢大家的帮助:)
编辑:谢谢你们,现在我终于明白发生了什么以及Python是如何工作的。非常感谢大家 :D
在此代码中:
command=comando_click("Nova_Mensagem")
您调用了 comando_click
函数一次,并将结果 (None
) 赋给了 command
参数。调用 command
时什么也不会发生(实际上你应该得到一个 TypeError
异常,因为 None
不可调用)。
在此代码中:
command=lambda:comando_click("Nova_Mensagem")
您实际上还没有调用 comando_click
-- 您创建了一个新函数(使用 lambda
),该函数将在调用时依次调用 comando_click
。每次单击按钮时,都会调用您的新函数。
如果 lambda
令人困惑,您可以像这样使用 def
做完全相同的事情:
def button_command():
comando_click("Nova_Mensagem")
...
command=button_command # no ()! we don't want to actually call it yet!
当您想创建一个不需要名称的小型一次性函数(例如,您想要创建一个函数调用带有特定参数的另一个函数,就像您在此处所做的那样。
问题是 comando_click("Nova_Mensagem")
您正在执行函数。所以命令=None.
在第二种情况下 lambda:comando_click("Nova_Mensagem")
返回一个内部调用 comando_click("Nova_Mensagem")
.
修复:只需输入 command=comando_click
.
如果你想用参数个性化 lambda,你可以这样写:
def handler(args):
def custom_handler():
print(args)
return custom_handler
botao = Button(menu_inicial, text = "Executar", command=handler("my custom string"))
当你使用()
和一个函数名(func(args)
)时,那么它立即calling/invoking函数而python正在执行该行,你不想要那个。您只想在单击按钮时调用该函数。 tkinter
将在内部为您调用该函数,您只需提供函数名称即可。
为什么要用lambda
?把它看成一个函数就是returns另一个函数,你的代码可以加长为:
func = lambda: comando_click("Nova_Mensagem")
botao = Button(menu_inicial, text = "Executar", command=func)
func
是函数名,如果你想调用它,你会说func()
。当你说 command=comando_click("Nova_Mensagem")
然后 command
有 command click
返回的值(因为你用 ()
调用函数),这是 None
如果我' m没有错,如果给定的值为None
,则不会被tkinter
调用。因此,由于 ()
,您的函数仅执行一次,并且作为调用该函数的结果,您在事件循环开始处理事件之前分配了函数调用 (None
) 的值。
其他一些方法:
- 使用
partial
来自functools
:
from functools import partial
botao = Button(.....,command=partial(comando_click,"Nova_Mensagem"))
- 使用助手函数:
def helper(args):
def comando_click():
print(args)
return comando_click
botao = Button(...., command=helper("Nova_Mensagem"))
IMO,lambda
s 是继续调用带有参数的函数的最简单方法。