1

基本上我有一系列在循环中创建的 OptionMenus,但目前是空的:

option_menu = []
for ii in range(jj):
    option_menu.append([])  
    for ll in range(kk):   
        option_menu[ii].append(OptionMenu(frame,tkinter_text_var[ii][ll],''))

然后在其他地方我使用一个复选框来设置沿线的值:

for ii in range(jj):
    for ll in range(kk):   
        option_menu[ii][ll]["menu"].add_command(label = name_from_box.get(), command = lambda: tkinter_text_var[ii][ll].set(name_from_box.get()))

这可以正确填充所有 OptionMenus,但是当我在任何 OptionMenus 中选择一个值时,它只设置 option_menu[jj][kk] (即最后一个)。

那么我做错了什么?

4

1 回答 1

4

这是一个涉及闭包的非常常见的问题。看下面的例子:

alist = [lambda : x for x in range(10) ]
print (alist[2]()) #9
print (alist[4]()) #9

都将是 9。为什么?因为每个 lambda 函数都引用了变量x. x在循环的每次迭代中都会更改,但它们仍然引用同一个 object

解决此问题的一种方法是使用默认参数。默认参数是在创建函数时评估的,而不是在调用它时评估的。

alist = [lambda y=x: y for x in range(10) ]
print (alist[2]()) #2
print (alist[4]()) #4

(做同样事情的另一种方法涉及functools.partial你有时会看到的......)

我经常喜欢说——“小心闭包”。他们可能有点棘手。

于 2012-08-03T18:24:12.987 回答