Python 2.7 动态分配按钮回调-Python

Python 2.7 动态分配按钮回调-Python,python-2.7,Python 2.7,所以我最近开始学习Python,我喜欢它。我想在我的第一个项目中创建一个计算器操作系统,我决定添加带有循环的按钮。但是按钮的回调始终是我希望作为回调函数的参数传递的变量的最后一个状态。这是我的密码 def addButtons(): buttons = [] label = "" num = 0 posX = 4 posY = 1 for i in range(12): if (i % 4 < 3): num += 1 label = str

所以我最近开始学习Python,我喜欢它。我想在我的第一个项目中创建一个计算器操作系统,我决定添加带有循环的按钮。但是按钮的回调始终是我希望作为回调函数的参数传递的变量的最后一个状态。这是我的密码

def addButtons():
buttons = []

label = ""
num = 0

posX = 4
posY = 1

for i in range(12):

    if (i % 4 < 3):
        num += 1
        label = str(num)
    else:
        label = "Blank"

    if (i % 4 == 0):
        posY += 1

    if (posX < 3):
        posX += 1
    else:
        posX = 0

    buttons.append(
        Button(buttonPanel, text=label, command=lambda: function(i), relief="flat", borderwidth=0, sticky=w, background="#fff", activebackground="#eee"))
    buttons[i].grid(column=posX, row=posY, sticky=N + S + E + W)

    buttonPanel.grid_columnconfigure(posX, weight=1)
    buttonPanel.grid_rowconfigure(posY, weight=1)

    functions.append(label)


def function(obj):  # the button's functions are identified by this function and executed respectively
    print obj
def addButtons():
按钮=[]
label=“”
num=0
posX=4
posY=1
对于范围(12)内的i:
如果(i%4<3):
num+=1
label=str(num)
其他:
label=“空白”
如果(i%4==0):
posY+=1
如果(posX<3):
posX+=1
其他:
posX=0
按钮。附加(
按钮(buttonPanel,text=label,command=lambda:function(i),relief=“flat”,borderwidth=0,sticky=w,background=“#fff”,activebackground=“#eee”))
按钮[i]。网格(列=posX,行=posY,粘性=N+S+E+W)
buttonPanel.grid\u columnconfigure(posX,权重=1)
buttonPanel.grid_rowconfigure(位置,重量=1)
函数。追加(标签)
def功能(obj):#按钮的功能由该功能识别并分别执行
打印对象
所以,当我点击一个按钮时,我总是从控制台得到11,不管是哪个按钮。有没有一种方法可以动态设置回调参数

谢谢你的帮助
-Jacob

您遇到的问题是,当您编写
lambda:function(i)
时,lambda函数不会保存
i
的当前值。相反,当它被调用时,它只在外部名称空间中查找它。这就是为什么在所有回调中都会看到
i
的最后一个值,因为这是它上次修改时的值

通过将名称
i
绑定到lambda中的特定值,可以避免此问题:

lambda i=i: function(i)
这有点滥用默认参数,但它完全符合您的要求。外部命名空间中的
i
的当前值被绑定为lambda函数命名空间中不同
i
变量的默认值。定义lambda时会发生这种情况,因此外部名称空间的
i
稍后更改值并不重要


另一种基本相同的方法是使用标准库的
functools
模块中定义的
partial
类型。它允许您将一些参数绑定到以后可以调用的函数。这在以后需要一些额外的参数时非常有用,但在这种情况下也会有所帮助。您可以将
partial(function,i)
作为回调来传递,而不是lambda。

工作非常完美,非常感谢!