3

我想了解按钮是如何使用 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()

但是当我点击它时我的按钮不起作用,当我运行代码时它只在控制台中显示一次打印,我在问题中添加了一些打印:

问题图一

好吧,似乎当我在按钮中使用 Lambda 函数时它起作用了,我真的很想知道为什么。

Lambda工作按钮图一

我刚刚在按钮上添加了 lambda :

botao = Button(menu_inicial, text = "Executar", command=lambda:comando_click("Nova_Mensagem"))

Lambda工作按钮图二

为什么使用 lambda 它可以工作?既然 lambda 基本上是一个匿名函数,它也不应该在没有 lambda 的情况下工作?

我非常想知道它为什么会起作用,谢谢大家的帮助:)

编辑:我要感谢你们,现在我终于明白发生了什么以及 Python 是如何工作的。非常感谢大家:D

4

3 回答 3

1

在这段代码中:

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!

当您想要创建一个不需要名称的小型一次性函数时,该lambda表达式只是使用的替代方法(例如,您想要创建一个函数来调用具有特定参数的另一个函数,就像您在此处所做的那样def)。

于 2021-12-18T19:27:27.723 回答
1

问题是comando_click("Nova_Mensagem")您正在执行该功能。所以命令=无。

在第二种情况下lambda:comando_click("Nova_Mensagem"),返回一个内部调用的 lambda 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"))
于 2021-12-18T19:27:34.477 回答
1

当您使用()函数名称(func(args))时,它会在 python 执行该行时立即调用/调用该函数,您不希望这样。您只想在单击按钮时调用该函数。tkinter将在内部为您调用该函数,您所要做的就是给出函数名称。

为什么使用lambda将其视为返回另一个函数的函数,您的代码可以延长为:

func  = lambda: comando_click("Nova_Mensagem")
botao = Button(menu_inicial, text = "Executar", command=func)

func是函数名,如果你想调用它,你会说func(). 当你说command=comando_click("Nova_Mensagem")thencommand有返回的值时command click(因为你用 调用函数()),None如果我没记错的话,如果给定的值是None,它不会被 调用tkinter。因此,您的函数只执行一次,因为()调用该函数,您None在事件循环开始处理事件之前分配了函数 call() 的值。

其他一些方法:

  • 使用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, lambdas 是使用参数调用函数的最简单方法。

于 2021-12-18T19:28:36.567 回答