本文通过一个小案例,来理解python中的引用和值
任务需求
在pyqt 界面中右侧有两个listWidget我们要获取用户的点击,并封装到一个参数类里
class DrawArgs:
def __init__(self, graph_type=None, way=None, type=None, value=None):
self.graph_type = graph_type
self.way = way
self.type = type or []
self.value = value or []
def is_ready(self):
return self.graph_type and self.way and self.type and self.value
def __eq__(self, other):
try:
return self.graph_type == other.graph_type and self.way == other.way and self.type == other.type and self.value == other.value
except:
return False
在为listWidget绑定槽时
self.graph_type_list.currentTextChanged.connect(self.set_draw_args)
self.way_list.currentTextChanged.connect(self.set_draw_args, )
为了复用self.set_draw_args函数。
我们在self.set_draw_args中进行if判断
def set_draw_args(self):
if self.sender() == self.graph_type_list:
self.draw_args.graph_type = self.sender().currentItem().text()
else:
self.draw_args.way = self.sender().currentItem().text()
但是可以看到 每个分支的逻辑很像,没必要进行if。我们很容易想到通过字典来简化写法,提高速度。
self.args_ui_dict = {self.graph_type_list:self.draw_args.graph_type,
self.way_list: self.draw_args.way,
self.type_list: self.draw_args.type,
self.value_list: self.draw_args.value}
def set_draw_args(self):
self.args_ui_dict[self.sender()] = self.sender().currentItem().text()
好,现在不要往下看,有人发现错误了吗。这个代码是无法生效的。
引用和值
我们把DrawArgs的属性放入到了字典中。但如果DrawArgs的属性是不可变类型int,str等实际上我们放的是值。这个更改不会修改self.draw_args里的属性。
当我们使用字典来代替if判断时,注意当我们的value是个变量,如果变量是不可变类型。我们直接修改,这个操作不会在原变量生效。
解决方案
如果我们还想使用字典来优化if。可以这样。
self.args_ui_dict ={self.graph_type_list: "graph_type",self.way_list:"way",
self.type_list: "type", self.value_list: "value"}
def set_draw_args(self):
setattr(self.draw_args, self.args_ui_dict[self.sender()], self.sender().currentItem().text())