Python类函数与主程序数组数据不同步问题求解
问题:Python类中操作defaultdict结构后无法同步更新的问题
我需要在Python类函数中操作一个defaultdict结构的多个部分,并返回与原结构一致的子结构。主程序通过返回值更新全局结构后,类函数却无法读取到新值;仅修改单个键值时有效,但替换整个子结构或扩展新键时失效,甚至报错。相关代码及运行现象如下:
代码文件
main.py
#!/usr/bin/env python # coding: utf8 from collections import defaultdict import test_class as sensors import copy SENSOR_config_array=defaultdict(dict) SENSOR_config_array["Sensors"]=defaultdict(dict) SENSOR_config_array["Sensors"]["actualVal"]=3 SENSOR_config_array["Sensors"]["maxVal"]=10 A10_sensors_class = sensors.deal_with_sensorData(SENSOR_config_array) print ("original SENSOR_config_array:") print (SENSOR_config_array) print() ret=A10_sensors_class.make_DataString() ## return "maxVal" should change to 20 print ("1. ret :") print (ret) ## OK print() SENSOR_config_array["Sensors"]["maxVal"]=20 ## "maxVal" set to 20 ret=A10_sensors_class.make_DataString() ## return "maxVal" should =40 print ("2. ret :") print (ret) ## OK SENSOR_config_array["Sensors"]=ret ## "maxVal" set to (returned)40 print ("2. SENSOR_config_array:") print (SENSOR_config_array["Sensors"]) ## 40 !!! it seems to be updated!!! print() ret=A10_sensors_class.make_DataString() ## return "maxVal" should =80 print ("3. ret:") print (ret) ## NO !! print() SENSOR_config_array["Sensors"]["Val"]=90 ret=A10_sensors_class.make_DataString2() ## return "maxVal" should =180 print ("4. ret:") print (ret) ## NO !! print()
test_class.py
#!/usr/bin/env python # coding: utf8 from collections import defaultdict class deal_with_sensorData: def __init__(self, config_data): self.SensorData=defaultdict(set) self.SensorData=config_data["Sensors"] ## config_data has e.g. ## config_data["Busses"]["type"] ## config_data["Sensors"]["actualVal"] ## config_data["Sensors"]["maxVal"] def make_DataString(self): temp=defaultdict(dict) temp["maxVal"]=self.SensorData["maxVal"]*2 return temp def make_DataString2(self): temp=defaultdict(dict) temp["Val"]=self.SensorData["Val"]*2 return temp
运行输出
original SENSOR_config_array: defaultdict(<class 'dict'>, {'Sensors': defaultdict(<class 'dict'>, {'actualVal': 3, 'maxVal': 10})}) 1. ret : defaultdict(<class 'dict'>, {'maxVal': 20}) 2. ret : defaultdict(<class 'dict'>, {'maxVal': 40}) 2. SENSOR_config_array: defaultdict(<class 'dict'>, {'maxVal': 40}) 3. ret: defaultdict(<class 'dict'>, {'maxVal': 40}) 4. ERROR
问题原因
- 对象引用不匹配:类的
__init__方法中,self.SensorData指向的是初始化时传入的config_data["Sensors"]对象。当主程序执行SENSOR_config_array["Sensors"]=ret时,是将全局的"Sensors"键指向了新的defaultdict对象,但类内部的self.SensorData仍然引用原来的旧对象,所以后续类函数读取的还是旧数据。 - 键不存在报错:步骤4中,全局的新
Sensors对象添加了"Val"键,但类里的self.SensorData还是旧对象,没有这个键,因此调用make_DataString2时会触发KeyError。
解决方案
方案1:修改子结构内部键值,不替换整个对象
不要直接替换SENSOR_config_array["Sensors"],而是遍历返回的ret,更新原有对象的键值对:
# 替换原来的 SENSOR_config_array["Sensors"]=ret for k, v in ret.items(): SENSOR_config_array["Sensors"][k] = v
这样类里的self.SensorData始终指向同一个对象,内部值更新后类函数能直接读取到最新数据。
方案2:让类持有顶层config_data引用
修改类的初始化逻辑,保存顶层的config_data引用,而非子级的Sensors对象:
# 修改test_class.py的__init__和方法 class deal_with_sensorData: def __init__(self, config_data): self.config_data = config_data # 保存顶层配置引用 def make_DataString(self): temp=defaultdict(dict) temp["maxVal"]=self.config_data["Sensors"]["maxVal"]*2 return temp def make_DataString2(self): temp=defaultdict(dict) temp["Val"]=self.config_data["Sensors"]["Val"]*2 return temp
无论主程序如何替换"Sensors"对应的对象,类都能通过顶层引用获取到最新的Sensors对象。
方案3:手动更新类内部的引用
每次替换全局的Sensors对象后,手动更新类里的self.SensorData:
# 在主程序执行 SENSOR_config_array["Sensors"]=ret 后添加 A10_sensors_class.SensorData = SENSOR_config_array["Sensors"]
强制让类内部的引用指向新的对象,后续类函数就能读取到最新数据。
内容的提问来源于stack exchange,提问作者apani
相关产品推荐
相关产品推荐

