Python计算器GUI按钮command参数中lambda函数写法疑问
Python Tkinter按钮command中Lambda函数的使用疑问
我对下面Python计算器GUI按钮创建语法里的lambda函数用法有疑问:我理解的lambda函数写法是示例1这种,但为什么在Tkinter Button构造器的command选项里可以用示例2的写法?我原本以为得写成command=lambda num: button_press(1)才能生效,搞不懂原因。
示例1:我熟悉的Lambda写法
>>> add_one = lambda x: x + 1 >>> add_one(2)
示例2:计算器代码中的Lambda写法
button1 = Button(frame,text=1,height=4,width=9,font=35, command=lambda: button_press(1))
计算器完整代码
from tkinter import * def button_press(num): global equation_text equation_text = equation_text + str(num) equation_label.set(equation_text) def equals(): global equation_text try: total = str(eval(equation_text)) equation_label.set(total) equation_text = total except SyntaxError: equation_label.set("syntax error") equation_text = "" except ZeroDivisionError: equation_label.set("arithmetic error") equation_text = "" def clear(): global equation_text equation_label.set("") equation_text = "" window = Tk() window.title("Calculator program") window.geometry("500x500") equation_text = "" equation_label = StringVar() label = Label(window, textvariable=equation_label, font=('consolas', 20),bg='white',width=24,height=2) label.pack() frame = Frame(window) frame.pack() button1 = Button(frame,text=1,height=4,width=9,font=35, command=lambda: button_press(1)) button1.grid(row=0,column=0) button2 = Button(frame,text=2,height=4,width=9,font=35, command=lambda: button_press(2)) button2.grid(row=0,column=1) button3 = Button(frame,text=3,height=4,width=9,font=35, command=lambda: button_press(3)) button3.grid(row=0,column=2) button4 = Button(frame,text=4,height=4,width=9,font=35, command=lambda: button_press(4)) button4.grid(row=1,column=0) button5 = Button(frame,text=5,height=4,width=9,font=35, command=lambda: button_press(5)) button5.grid(row=1,column=1) button6 = Button(frame,text=6,height=4,width=9,font=35, command=lambda: button_press(6)) button6.grid(row=1,column=2) button7 = Button(frame,text=7,height=4,width=9,font=35, command=lambda: button_press(7)) button7.grid(row=2,column=0) button8 = Button(frame,text=8,height=4,width=9,font=35, command=lambda: button_press(8)) button8.grid(row=2,column=1) button9 = Button(frame,text=9,height=4,width=9,font=35, command=lambda: button_press(9)) button9.grid(row=2,column=2) button0 = Button(frame,text=0,height=4,width=9,font=35, command=lambda: button_press(0)) button0.grid(row=3,column=0) plus = Button(frame,text='+',height=4,width=9,font=35, command=lambda: button_press('+')) plus.grid(row=0,column=3) minus = Button(frame,text='-',height=4,width=9,font=35, command=lambda: button_press('-')) minus.grid(row=1,column=3) multiply = Button(frame,text='*',height=4,width=9,font=35, command=lambda: button_press('*')) multiply.grid(row=2,column=3) divide = Button(frame,text='/',height=4,width=9,font=35, command=lambda: button_press('/')) divide.grid(row=3, column=3) equal = Button(frame,text='=',height=4,width=9,font=35, command=equals) equal.grid(row=3,column=2) decimal = Button(frame,text='.',height=4,width=9,font=35, command=lambda: button_press('.')) decimal.grid(row=3,column=1) clear = Button(window,text='clear',height=4,width=9,font=35, command=clear) clear.pack() window.mainloop()
问题解答
核心原因是Tkinter触发按钮点击时,会调用command指定的函数,且不会传递任何参数:
- 示例1的
lambda x: x + 1是带参数的lambda,它要求调用时必须传入一个参数,但Tkinter不会传参,这种写法放到command里会直接报错,因为lambda期望1个参数却没收到。 - 示例2的
lambda: button_press(1)是无参数lambda,刚好匹配Tkinter的调用规则:点击按钮时,Tkinter调用这个lambda,它不需要任何参数,内部直接把固定值1传给button_press执行。
你之前想的lambda num: button_press(1)完全多余:这个lambda定义了参数num,但Tkinter不会给它传值,而且lambda内部也没用到这个参数,纯粹多此一举。
另外补充:为什么不直接写command=button_press(1)?因为这样写的话,Python在创建按钮的瞬间就会执行button_press(1),而不是等到按钮点击时才触发。lambda的作用就是延迟执行,把函数调用包装成一个可调用对象,只有触发点击事件时才会运行内部的代码。
内容的提问来源于stack exchange,提问作者Casey Wong
相关产品推荐
相关产品推荐

