先上一段代码看问题
from tkinter import *
root = Tk()
def appear(index, letter):
print(index, letter)
entry.insert(0, f'{index}:{letter},')
buttons[index].config(state="disabled")
letters=["A", "B", "C", "D", "E", "F", "S", "R", "M"]
buttons = []
for index in range(len(letters)):
n = letters[index]
button = Button(root, bg="White", text=n, width=5, height=1, relief=GROOVE, command=lambda: appear(index, n))
# Add the button to the window
button.grid(padx=2, pady=2, row=int(index%3), column=int(index/3))
# Add a reference to the button to 'buttons'
buttons.append(button)
Label(root, text="Get: ").grid(row=3, column=0)
entry = Entry(root, width=15)
entry.grid(pady=2, row=3, column=1, columnspan=2)
root.mainloop()
按理论来说, 点击对应的按键应该获得对应的字母和索引,可实际情况点击按钮,但是得到的字母都是最后一个“M”和索引:
如图点击A,E,M的效果
解决方法
将lambda 传递的参数转一下再传递
button = Button(root, bg="White", text=n, width=5, height=1, relief=GROOVE,
command=lambda i=index, s=n: appear(i, s))
试试效果
问题出在哪呢?
看看相关问题的链接和lambda没有你想的那么简单
继续看代码说话:
li = []
for x in range(5):
li.append(lambda n: n*x)
print(li[0](2)) # 8
print(li[1](3)) # 12
print(li[2](4)) # 16
看出问题没
其传参中的x并不是当时x的值,而是一个地址,循环结束时x=4,所以li中所有的元素中的x都是4,同理,第一个例子参数都是8和M
当你将参数赋给另外的变量再传递给lambda 时其获取结果的地址变成你赋给的值,自然就是你想要的结果了
li = []
for x in range(5):
li.append(lambda n, m=x: n*m)
print(li[0](2)) # 0
print(li[1](3)) # 3
print(li[2](4)) # 8