问题遇到的现象和发生背景
初学python,遇到个小问题,代码如下。
字符串变量some_str在定义信号连接之后,值会改变。
我希望按下按钮时,用匿名函数打印变量some_str的初始值,而不是改变后的值。
我弄了几个按钮来尝试这个功能,其实已经解决了,用btn3的方案就行。
问题是,btn1的lambda local_var=some_str: print(local_var)并没有正确地保存local_var的初始值,在调用时变成False了。
这是为什么?
问题相关代码,请勿粘贴截图
import functools
import os
from PyQt5 import QtWidgets
class MainWidget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(MainWidget, self).__init__(parent)
layout = QtWidgets.QGridLayout(self)
# 定义按钮
self.btn0 = QtWidgets.QPushButton(text='按钮0')
self.btn0.setObjectName('btn0')
layout.addWidget(self.btn0, 0, 0)
self.btn1 = QtWidgets.QPushButton(text='按钮1')
self.btn1.setObjectName('btn1')
layout.addWidget(self.btn1, 1, 0)
self.btn2 = QtWidgets.QPushButton(text='按钮2')
self.btn2.setObjectName('btn2')
layout.addWidget(self.btn2, 2, 0)
self.btn3 = QtWidgets.QPushButton(text='按钮3')
self.btn3.setObjectName('btn3')
layout.addWidget(self.btn3, 3, 0)
# 变量初始值
some_str = 'a'
print('变量some_str的初始值为:', some_str)
# 信号连接
self.btn0.clicked.connect(lambda: print(some_str))
self.btn1.clicked.connect(lambda local_var=some_str: print(local_var))
self.btn2.clicked.connect(eval(f'lambda: print(\'{some_str!s}\')'))
self.btn3.clicked.connect(
functools.partial(lambda arg: print(arg), some_str))
# 修改变量
some_str = 'b'
print('变量some_str修改后值为:', some_str)
print('我希望按下按钮时,用匿名函数打印变量some_str的初始值')
print('==========')
if __name__ == '__main__':
import sys
os.chdir(os.path.dirname(__file__))
app = QtWidgets.QApplication(sys.argv)
main_w = MainWidget()
main_w.show()
sys.exit(app.exec_())
运行结果及报错内容
几个按钮的返回值:
按钮0返回b(错误),因为调用lambda时some_str的值已经改成了b。
按钮1返回False(错误),我认为应该保存了定义时上下文的变量值,但奇怪的是,调用时这个值变成False了,为啥?
按钮2返回a(正确),代码太丑。
按钮3返回a(正确),最终采用。
我的解答思路和尝试过的方法
我想要达到的结果
我想搞清楚按钮1的local_var到底为啥会变成False。