2014-05-20 5 views
2

사용자 인터페이스를 통해 수정되는 사전을 보관합니다. 사용자가 제어하는 ​​'저장'기능을 사용하는 대신 사전이 변경 될 때마다 JSON 파일에 작성되도록하고 싶습니다. 나는 저장의 메카니즘을 알고 있지만, 사전의 변경을 저장하는 방법을 알지 못한다. 이것이 가능한가요, 그렇다면 어떻게 될까요?변경 될 때 사전 저장

+0

JSON 형식이 아닐지라도 'shelve'와 정확히 일치합니다. – roippi

+0

@roippi :'shelve'도'collections.MutableMapping'을 사용합니다. –

답변

4

기본값은 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 형식의 파일이 아니지만 자동으로 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']})> 
관련 문제