Python lambda按值传递可变对象

时间:2018-03-19 19:33:02

标签: python lambda pyqt5 signals-slots

经过大量的研究,包括on stackoverflow,我真的无法理解为什么即使我将变量的默认值设置为很多人推荐之后,下面的代码也不起作用。这是代码

#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个按钮,每个按钮都有各自的名称(name1,name2,name3)但是当我点击它们时,它会打印

False
False 
False

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

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

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

1 个答案:

答案 0 :(得分:0)

我想你显然忘了按"保存"添加value=…之后。

如果我重播你的问题

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变量,只获取其最后一个持久值。

另一种方法是将lambda链接到创建时最新的值,并且应该可以正常工作。 (请注意,我没有使用按钮进行操作,而是专注于labda问题。)

另一种方法是拥有一个创造"打印机"根据需要:

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

使用它们,您可以轻松创建可以根据需要执行的lambda:打印给定值,例如

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