Python lambda 传值可变对象

Python lambda pass-by-value mutable objects

经过大量研究,包括在 Whosebug 上,我真的不明白为什么即使我按照很多人的建议设置了我的变量的默认值,下面的代码也不起作用。这是代码

#initial nested array
outter = [["name1",1],["name2",2],["name3",3]]

for inner in outter:
    button = QPushButton()
    button.setText(inner[0])  // create a button with the text
    button.clicked.connect(lambda value=inner[1] : print(value))

创建了 3 个按钮,每个按钮都有各自的名称(名称 1、名称 2、名称 3),但是当我单击它们时,它会打印

False
False 
False

如果我更改这部分代码,所有 3 个按钮都会打印最后一个值“3”,如下所示,

 button.clicked.connect(lambda : print(inner[1]))
 3
 3
 3

我已经尝试过做各种疯狂的事情来完成这项工作,有什么建议吗?

我想你显然是在添加 value=… 之后忘记按 "save"。

如果我重播你的问题

outer = [["name1",1],["name2",2],["name3",3]]

# this must have been your original approach and was the same as in the linked question
ll = [lambda: inner[1] for inner in outer]
print(ll[0](), ll[1](), ll[2]()) # gives 3 3 3

# your approach
ll = [lambda value=inner[1]: value for inner in outer]
print(ll[0](), ll[1](), ll[2]()) # gives 1 2 3

# alternative approach
ll = [lambda value=inner: value[1] for inner in outer]
print(ll[0](), ll[1](), ll[2]()) # gives 1 2 3

previously linked question 中所述,lambda 始终通过其闭包访问 inner 变量,仅获取其最后一个持久值。

替代方法是 link 将 lambda 转换为创建时的当前值并且应该绝对有效。 (请注意,我不是用按钮来解决问题,而是专注于 labda 问题。)

另一种方法可能是拥有一个根据需要创建 "printers" 的函数:

def printer(value):
    return lambda: print(value)

有了它们,您可以轻松创建随心所欲的 lambda:打印给定的值,例如

button.clicked.connect(printer(inner[1]))print(value))