I am writing a class that acts as a dictionary but saves its content to a json file each time a modification is made to ensure a synchronous state.
However I stumbled upon a special case that breaks my synchronization : when appending a value to a list inside the dictionary.
Since this uses __getitem__, how can I make sure that if the item returned is modified, I save it to the JSON file ?
Here is a fully functional code snippet (Python 3.9.2) to illustrate what I mean
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