我目前正在尝试用Python编写井字游戏的GUI。为此,我正在使用tkinter。我想为每个位置创建一个按钮,以便通过单击这些按钮之一进行移动。现在的问题是,我希望根据单击的按钮来调用具有不同参数的函数。因此,我尝试使用lambda表达式,但是无论我单击哪个按钮,它都会导致相同的调用。
import tkinter as tk
class GameWindow:
def __init__(self):
win = tk.Tk()
buttons = [[tk.Button(win,text=str(i)+str(j)) for j in range(3)] for i in range(3)]
for i in range(3):
for j in range(3):
buttons[i][j]["command"] = lambda: print([i,j])
buttons[i][j].grid(row=i, column=j)
print([i,j])
win.mainloop()
test = GameWindow()
在这种情况下,我只希望打印位置,但是无论我单击哪个按钮,都将打印[2,2]。
答案 0 :(得分:1)
您看到的问题是由于您已经创建了一个闭合。这意味着在其中创建lambda
的堆栈框架保持活动状态,并且lambda
引用这些变量的 current 值,而不是创建它们时的值。您可以通过执行以下操作来捕获它们的值:
def make_lambda(i, j):
return lambda: print([i, j])
然后在您的代码中,替换:
buttons[i][j]["command"] = lambda: print([i,j])
具有:
buttons[i][j]["command"] = make_lambda(i, j)
这将捕获并保留调用make_lambda
时的值。这将是一个闭包,但其框架将退出,返回的lambda将是对此的唯一剩余引用。