2
我保持一個字典,正在通過用戶界面進行修改。代替具有用戶控制的「保存」功能,我希望字典在其更改時寫入JSON文件。我知道保存的機制,但不知道如何觸發字典中更改的保存。這是可能的,如果是的話,如何?保存字典,當它改變
我保持一個字典,正在通過用戶界面進行修改。代替具有用戶控制的「保存」功能,我希望字典在其更改時寫入JSON文件。我知道保存的機制,但不知道如何觸發字典中更改的保存。這是可能的,如果是的話,如何?保存字典,當它改變
您不能使用默認的dict
類型,但可以使用自定義字典子類或collections.MutableMapping
abstract base class的子類以及攔截方法來修改字典,以便觸發保存。
對後者最簡單;它將所有修改方法映射到__setitem__
。您需要提供overview table的抽象方法列中的所有方法。
這裏是我的這樣一類的速寫:
import json
from collections import MutableMapping
class JSONBackedMapping(MutableMapping):
def __init__(self, filename, initial=None, **kw):
self._filename = filename
try:
# Try and load the file
self.load()
except (ValueError, IOError):
# failure, fall back to the initial object
self._data = initial or {}
self._data.update(**kw)
def load(self):
with open(self._filename, 'r') as inf:
self._data = json.load(inf)
def save(self):
with open(self._filename, 'w') as outf:
json.dump(self._data, outf)
def __repr__(self):
return '<{}({!r}, {})>'.format(
type(self).__name__,
self._filename, self._data)
def __len__(self): return len(self._data)
def __iter__(self): return iter(self._data)
def __getitem__(self, item): return self._data[item]
def __delitem__(self, item):
del self._data[item]
self.save()
def __setitem__(self, item, value):
self._data[item] = value
self.save()
這會從所給的文件加載,或者如果失敗與初始字典開始。您可以添加其他鍵值對作爲關鍵字參數。它所做的任何更改將被自動保存爲JSON給定文件名:
>>> data = JSONBackedMapping('data.json')
>>> data
<JSONBackedMapping('data.json', {})>
>>> data['foo'] = 'bar'
>>> data['spam'] = ['eggs', 'ham']
>>> print open('data.json').read()
{"foo": "bar", "spam": ["eggs", "ham"]}
>>> del data
>>> data = JSONBackedMapping('data.json')
>>> data
<JSONBackedMapping('data.json', {u'foo': u'bar', u'spam': [u'eggs', u'ham']})>
FYI這正是'shelve'呢,雖然不是以JSON格式。 – roippi
@roippi:和'shelve'也使用'collections.MutableMapping'。 –