Python 什么';lambda有什么问题(可能与PyQt有关?)

Python 什么';lambda有什么问题(可能与PyQt有关?),python,python-3.x,pyqt5,Python,Python 3.x,Pyqt5,我将三个按钮连接到一个函数,该函数接受一个参数并简单地打印它。按钮以不同的方式传递参数,正如您在下面的MWE中看到的,尽管据我所知,没有任何语义差异 from PyQt5.QtWidgets import QPushButton, QFrame, QApplication, QVBoxLayout from functools import partial def func(i): print(i) app = QApplication([]) frame = QFrame() l

我将三个按钮连接到一个函数,该函数接受一个参数并简单地打印它。按钮以不同的方式传递参数,正如您在下面的MWE中看到的,尽管据我所知,没有任何语义差异

from PyQt5.QtWidgets import QPushButton, QFrame, QApplication, QVBoxLayout
from functools import partial


def func(i):
    print(i)

app = QApplication([])
frame = QFrame()
layout = QVBoxLayout()
frame.setLayout(layout)

b1 = QPushButton('button 1', frame)
b1.clicked.connect(lambda: func(1))

b2 = QPushButton('button 2', frame)
b2.clicked.connect(partial(func, i=2))

b3 = QPushButton('button 3', frame)
b3.clicked.connect(lambda x=3: func(x))

layout.addWidget(b1)
layout.addWidget(b2)
layout.addWidget(b3)

frame.show()
app.exec()
因此,当我单击按钮1到3时,我希望看到

1
2
3
但是我得到了

1
2
False
最后一个兰姆达怎么了?这可能是PyQt的一个bug吗


PyQt版本为5.15.2。

您可以使用默认值创建lambda:

lambda x=3: func(x)

但是Qt将False传递给它(选中的
参数),因此没有使用默认参数。

我认为这是因为PyQt将参数传递给connect函数。从继承的
QPushButton
中,单击的
插槽(PyQt中信号的回调称为插槽)将接收一个
选中的
参数,该参数为布尔值。lambda函数
lambda x=3:func(x)
采用一个参数
x
,该参数采用默认值3。如果未向该插槽传递任何参数,
x
因此将取值3。但是,PyQt将
False
传递给此函数,如
单击的
信号文档中所指定,因此
x
取而代之的是将x与返回False的3进行比较的值
False

。试试这个:
(lambda x:func(x))(3)
为什么
lambda:func(1)
没有失败呢?Qt是否检查函数是否接受参数?在这种情况下,lambda不使用参数并使用值
1
调用func。这与使用默认值不同。不使用默认值是什么意思?为什么它不会像
(lambda:func(1))(False)
那样失败,带有
TypeError:()接受0个位置参数,但给出了1个
?我认为,如果回调没有接受参数以使框架更易于使用,则Qt不会传递参数。PyQt始终调用插槽,无论其参数是否少于信号提供的参数。如果信号有两个参数,而函数只取一个参数,则仍将使用第一个信号参数调用函数。如果函数不带参数,则在发出信号时仍会调用它,即使它有参数。我感谢您的快速回复。Maxime Chéramy的回答更快(如果我们计算评论的话,与你的答案相同),所以我接受了他的答案。我对这个答案做了+1,因为我知道它总是受到赞赏:)。