gpt4 book ai didi

python - Python 中的 JSON 同步字典 : dealing with temporary references

转载 作者:行者123 更新时间:2023-12-03 17:09:13 25 4
gpt4 key购买 nike

我正在编写一个充当字典的类,但每次进行修改以确保同步状态时,都会将其内容保存到 json 文件中。
但是,我偶然发现了一个中断同步的特殊情况:将值附加到字典中的列表时。
由于这使用 __getitem__ ,如何确保如果返回的项目被修改,我将其保存到 JSON 文件中?
这是一个功能齐全的代码片段(Python 3.9.2)来说明我的意思

import json


class SyncDictJSON(dict):
__instances: dict = {}

@classmethod
def create(cls, filepath: str, **kwargs):
if filepath not in SyncDictJSON.__instances:
SyncDictJSON.__instances[filepath] = cls(filepath, **kwargs)
return SyncDictJSON.__instances[filepath]

def __init__(self, filepath: str, **kwargs):
super().__init__(**kwargs)
self.filepath = filepath
self.update(SyncDictJSON.read_data_from_filename(self.filepath))

def __getitem__(self, item):
print(f"getitem {item}")
return super(SyncDictJSON, self).__getitem__(item)

def __setitem__(self, key, value):
print(f"set item {key},{value}")
super().__setitem__(key, value)
SyncDictJSON.write_data_to_filename(self, self.filepath)

def __delitem__(self, key):
super().__delitem__(key)
SyncDictJSON.write_data_to_filename(self, self.filepath)

@staticmethod
def write_data_to_filename(data, filepath: str):
with open(filepath, "w", encoding="utf-8") as file:
json.dump(data, file, indent=2, ensure_ascii=False)

@staticmethod
def read_data_from_filename(filename: str):
with open(filename, "r", encoding="utf-8") as file:
return json.load(file)

@classmethod
def from_file(cls, filepath):
return cls(filepath)


if __name__ == '__main__':
with open("testing.json", "w") as file:
file.write("{}")
dico = SyncDictJSON.create("testing.json")

dico["a_list"] = []
dico["a_list"].append(5)

print(dico) # {'a_list': [5]} but testing.json will be empty

最佳答案

SyncDictJSON对象将记录对字典的更改。然而,一旦a_list 的列表被创建,附加到它不会改变字典;
字典将包含对列表的引用 [5] ,这仍然是一样的
引用当该列表为空时。
要记录附加到列表,您也可以使用以下代码,其中
包裹类 list成一个类似的包装。它依赖于对
同步字典被传递到列表,所以它需要一个
一点额外的空间。如果您打算删除列表项和/或插入它们,
您需要覆盖 SyncList 中的这些方法, 也。

import json

class SyncList(list):
def __init__(self, container, *args, **kwargs):
print('list init', *args, **kwargs)
self._container = container
super().__init__(*args, **kwargs)

def append(self, x):
print('list.append', self, x)
super().append(x)
self._container.write_data_to_filename(
self._container, self._container.filepath)


class SyncDictJSON(dict):
__instances: dict = {}

@classmethod
def create(cls, filepath: str, **kwargs):
if filepath not in SyncDictJSON.__instances:
SyncDictJSON.__instances[filepath] = cls(filepath, **kwargs)
return SyncDictJSON.__instances[filepath]

def __init__(self, filepath: str, **kwargs):
super().__init__(**kwargs)
self.filepath = filepath
self.update(SyncDictJSON.read_data_from_filename(self.filepath))

def __getitem__(self, item):
print(f"getitem {item}")
return super(SyncDictJSON, self).__getitem__(item)

def __setitem__(self, key, value):
print(f"set item {key},{value}")
super().__setitem__(key, value)
SyncDictJSON.write_data_to_filename(self, self.filepath)

def __delitem__(self, key):
super().__delitem__(key)
SyncDictJSON.write_data_to_filename(self, self.filepath)

@staticmethod
def write_data_to_filename(data, filepath: str):
with open(filepath, "w", encoding="utf-8") as file:
json.dump(data, file, indent=2, ensure_ascii=False)

@staticmethod
def read_data_from_filename(filename: str):
with open(filename, "r", encoding="utf-8") as file:
return json.load(file)

@classmethod
def from_file(cls, filepath):
return cls(filepath)


if __name__ == '__main__':
with open("testing.json", "w") as file:
file.write("{}")
dico = SyncDictJSON.create("testing.json")
dico["a_list"] = SyncList(dico, [])
dico["a_list"].append(5)
print(dico) # {'a_list': [5]}; testing.json will have the same
# list init []
# set item a_list,[]
# getitem a_list
# list.append [] 5
# {'a_list': [5]}

关于python - Python 中的 JSON 同步字典 : dealing with temporary references,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66933371/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com