我保留了一个通过用户界面修改的字典。我不想拥有用户控制的“保存”功能,而是希望每次更改时都将字典写入JSON文件。我知道保存的机制,但不知道如何触发字典中的更改保存。这是可能的,如果是的话,怎么样?
答案 0 :(得分:4)
您不能使用默认的dict
类型,但您可以使用自定义字典子类或collections.MutableMapping
abstract base class的子类,并拦截更改字典的方法,以便您可以触发保存。< / p>
后者最简单;它将所有修改方法映射到__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']})>