Python 二维数组中的Tkinter按钮绑定到同一命令

Python 二维数组中的Tkinter按钮绑定到同一命令,python,tkinter,Python,Tkinter,我正在制作一个简单的程序,创建一个3x3矩阵的tkinter.Button(),当按下一个按钮时,它应该会显示“单击”的文本。 但结果似乎是位于同一列上的按钮绑定到了同一个命令,该命令以该列最后一行的按钮为目标 from tkinter import * root = Tk() text = [[None]*3]*3 buttons = [[None]*3]*3 def action(i, j): text[i][j].set('Clicked') for i in range(

我正在制作一个简单的程序,创建一个3x3矩阵的
tkinter.Button()
,当按下一个按钮时,它应该会显示“单击”的文本。 但结果似乎是位于同一列上的按钮绑定到了同一个命令,该命令以该列最后一行的按钮为目标

from tkinter import *

root = Tk()

text = [[None]*3]*3
buttons = [[None]*3]*3

def action(i, j):
    text[i][j].set('Clicked')

for i in range(3):
    for j in range(3):
        text[i][j] = StringVar()
        text[i][j].set('(%d, %d)' % (i,j))
        buttons[i][j] = Button(root, command = lambda i=i, j=j : action(i, j))
        buttons[i][j].config(textvariable = text[i][j], width = 9, height = 5)
        buttons[i][j].grid(row = i, column = j)

root.mainloop()

问题不在于您的命令,而在于您创建列表的方式

当您将一个列表相乘时,实际上是将对该列表的引用相乘(请参阅)。运行以下代码时可以看到这一点:

text = [[None]*3]*3
print([id(x) for x in text])
因此,当您更改其中一个列表中的项目时,所有列表中的项目都会更改。因此,您的列表看起来不像
[[1,2,3],[4,5,6],[7,8,9]
,而是像
[[7,8,9],[7,8,9],[7,8,9]
。然后,当您认为您设置了StringVar编号1时,实际上您设置了StringVar编号7,所以按钮编号7被更改

您可以使用列表理解而不是乘法来创建三个单独的列表。正如您在下面的代码中看到的,这将生成三个单独的列表

text = [[None]*3 for _ in range(3)]
print([id(x) for x in text])