更改时保存字典

时间:2014-05-20 16:38:06

标签: python

我保留了一个通过用户界面修改的字典。我不想拥有用户控制的“保存”功能,而是希望每次更改时都将字典写入JSON文件。我知道保存的机制,但不知道如何触发字典中的更改保存。这是可能的,如果是的话,怎么样?

1 个答案:

答案 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']})>