所以我子類化一個Python dict
,大致是這樣的:Synchonize屬性更改在Python
class JSONDict(dict):
@property
def __json__(self):
return json.dumps(self)
@property
def __path__(self):
return os.path.join(settings.BASE_PATH, self.entity, 'settings.json')
def __init__(self, entity, *args, **kwargs):
dict.__init__(self)
self.entity = entity
try:
os.utime(self.__path__, None)
except OSError:
open(self.__path__, 'a').close()
self.__file__ = open(self.__path__, 'r+')
self.__to_python__()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
self.__file__.close()
def __to_json__(self):
self.__file__.seek(0)
self.__file__.write(self.__json__)
self.__file__.flush()
self.__file__.truncate()
def __to_python__(self):
if os.path.getsize(self.__path__):
self.__file__.seek(0)
dict.clear(self)
dict.update(self, json.load(self.__file__))
else:
self.clear()
def __getitem__(self, key):
self.__to_python__()
return dict.__getitem__(self, key)
def __setitem__(self, key, value):
dict.__setitem__(self, key, value)
self.__to_json__()
def update(self, data):
dict.update(self, data)
self.__to_json__()
def clear(self):
dict.clear(self)
self.update(__default__)
self['nar'] = self.nar
我可以用這個相當精細,例如:
>>> with JSONDict('entity-id') as json_info:
... json_info['setting_a'] = 'foo'
然而,有一個有趣的問題當涉及到名單。當我直接修改列表時,例如json_info['setting_b'].append('bar')
,JSON文件不會被更新。我肯定覆蓋__setitem__
和__getitem__
將涵蓋所有項目訪問,但顯然情況並非如此。我應該重寫什麼來完成這項工作?
UPDATE:
讀了第一的答案,我覺得這個問題是不是在正確的方式制定。正確的問題是,如何有效地觀察字典屬性的變化,以便能夠相應地更新JSON?應該通過代理/描述符對象,元類來完成,還是有更通用的方法?
'列表'只是一個'列表'。 –
注意,你真的不應該定義你自己的雙下劃線方法。只需將它們稱爲'to_json','to_python'等。 –
關鍵是,列表的**引用不會改變,所以'JSONDict'我們不知道其發生在其子節點(和子節點一般)。沒有向父母報告兒童的更新。 –