子类化dict从JSON文件初始化值未达预期问题
子类化dict实现自动读取JSON文件的问题解决
问题场景
拥有C/C++开发背景,尝试子类化dict实现自动读取JSON文件的功能,代码如下:
import json class DictFromJSON(dict): def get_from_file(self, filename): with open(filename,) as file_reader: self = json.load(file_reader) print(self) def save(self, filename): with open(filename, "w") as file_writer: json.dump(self, file_writer) def __setitem__(self, key, value): super().__setitem__(key, value) self.save() def __init__(self, filename, *args): super().__init__(args) self.get_from_file(filename) json_dict = DictFromJSON("myjson.json") print(json_dict)
测试JSON文件内容为{"mykey": true},运行后输出:
{'mykey': True} {}
get_from_file内部打印的self符合预期,但外部打印类实例时为空。
问题原因
Python中self是方法的局部变量,在get_from_file里执行self = json.load(file_reader),只是让局部变量self指向了json.load返回的新dict对象,并没有修改原来的DictFromJSON实例本身。原来的实例还是__init__中初始化的空dict,所以外部打印结果为空。
另外两处细节问题:
__init__里的super().__init__(args)错误:args是元组,直接传入会把元组作为单个键值对的键,应该用super().__init__(*args)解包参数。__setitem__里的self.save()缺少文件名参数,会直接触发调用报错。
修正后的代码
import json class DictFromJSON(dict): def __init__(self, filename, *args, **kwargs): super().__init__(*args, **kwargs) self.filename = filename # 把文件名保存为实例属性 self.get_from_file() def get_from_file(self): with open(self.filename) as file_reader: loaded_data = json.load(file_reader) self.clear() # 清空当前实例原有内容 self.update(loaded_data) # 将JSON加载的内容更新到当前实例 print(self) def save(self): # 直接使用实例保存的文件名,无需重复传入 with open(self.filename, "w") as file_writer: json.dump(self, file_writer) def __setitem__(self, key, value): super().__setitem__(key, value) self.save() # 测试 json_dict = DictFromJSON("myjson.json") print(json_dict) json_dict["new_key"] = "new_value" # 修改后会自动保存到文件
关键修改说明
- 避免直接给
self赋值,改用self.clear()+self.update()修改当前实例的内容,确保操作的是原对象 - 在
__init__中保存文件名到实例属性,简化后续方法的调用逻辑 - 修正父类构造方法的参数传递方式,正确解包
*args和**kwargs - 调整
save方法的参数逻辑,直接复用实例保存的文件名
内容的提问来源于stack exchange,提问作者Kiwewi
相关产品推荐
相关产品推荐

