Python Tkinter命令:lambdas中的函数参数?

Python Tkinter命令:lambdas中的函数参数?,python,for-loop,button,tkinter,lambda,Python,For Loop,Button,Tkinter,Lambda,我的程序有一个lambda作为循环中tkinter对象的命令。我希望lambda为函数传递一个参数,函数将根据参数进行一些更改 for cat in self.t_m_scope: print(cat) self.t_m_scopeObj[cat] = [tk.Checkbutton(self, text = cat, command = lambda: self.t_m_checkUpdate(cat)), []] if self.t_m_sco

我的程序有一个lambda作为循环中tkinter对象的命令。我希望lambda为函数传递一个参数,函数将根据参数进行一些更改

for cat in self.t_m_scope:
        print(cat)
        self.t_m_scopeObj[cat] = [tk.Checkbutton(self, text = cat, command = lambda: self.t_m_checkUpdate(cat)), []]
        if self.t_m_scopeVars[cat][0]: self.t_m_scopeObj[cat][0].toggle()
        self.t_m_scopeObj[cat][0].grid(row = 5, column = colNum, padx = (10,10), pady = (2,5), sticky = tk.W)
每当我尝试运行它时,它总是在cat的最后一次迭代中通过,因为tkinter命令中有一些奇怪的特性。相反,我希望参数与定义lambda时的迭代完全匹配。我不希望参数仅仅因为在迭代后单击了check按钮而改变

以下是lambda调用的函数

def t_m_checkUpdate(self, cat):
    self.t_m_scopeVars[cat][0] = not self.t_m_scopeVars[cat][0]
    for subcat in range(len(self.t_m_scopeVars[cat][1])):
        if self.t_m_scopeVars[cat][0] != self.t_m_scopeVars[cat][1][subcat]:
            self.t_m_scopeVars[cat][1][subcat] = not self.t_m_scopeVars[cat][1][subcat]
            self.t_m_scopeObj[cat][1][subcat].toggle()
作为这个程序的上下文,我试图让一堆checkbutton在点击主checkbutton时开关。我知道切换哪些复选按钮的唯一方法是使用lambda将参数传递给函数,因为我有很多复选按钮

我知道我可以使用if/elif/else找到当前迭代的值,并传递字符串而不是变量,但我真的不想这样做,因为它不可伸缩

如果有帮助的话,我的checkbutton和我想要传递的参数的文本是一个相同的文本


有没有什么变通方法可以让我保留当前迭代而不让Tkinter变得不稳定?

在创建函数时,需要将cat中的数据绑定到函数。有关说明,请参阅。有几种方法可以做到这一点,包括和

以下是您将如何在示例中应用分部:

from functools import partial
for cat in ...:
        check_update_cat = partial(self.t_m_checkUpdate, cat)
        self.t_m_scopeObj[cat] = [tk.Checkbutton(self, text=cat, command=check_update_cat), []]
a = []
for i in range(5):
    a.append(lambda: i)
a[0]()  # returns 4
a[1]()  # also returns 4
del i   # if we delete the variable leaked by the for loop
a[0]()  # raises NameError, i is not defined because the lambdas refer to i by reference
解释 在代码中,lambda引用循环外部范围中声明的迭代器变量cat。需要注意的一点是,循环的作用域泄漏了迭代器变量,也就是说,您仍然可以在循环之后访问它。lambda函数通过引用引用迭代器变量,因此它们访问迭代器的最新值

一个可运行的示例:

from functools import partial
for cat in ...:
        check_update_cat = partial(self.t_m_checkUpdate, cat)
        self.t_m_scopeObj[cat] = [tk.Checkbutton(self, text=cat, command=check_update_cat), []]
a = []
for i in range(5):
    a.append(lambda: i)
a[0]()  # returns 4
a[1]()  # also returns 4
del i   # if we delete the variable leaked by the for loop
a[0]()  # raises NameError, i is not defined because the lambdas refer to i by reference
相反,我们希望在每一步将迭代器的值绑定到函数。我们需要在这里复制迭代器的值

import functools
a = []
for i in range(5):
    a.append(functools.partial(lambda x: x, i)) # i is passed by value here
a[0]() # returns 0
a[1]() # returns 1
del i  
a[0]() # still returns 0

不会在循环中的每次迭代中检查\u update\u cat change,从而导致与我之前遇到的问题相同的问题吗?不,我在答案中添加了一个解释和可运行的示例。希望这能澄清问题,这能回答你的问题吗?