3

Say I have something like this (not tested):

class Foo(object):
    def __init__(self):
        self.store = {}

    def __setitem__(self, key, value):
        self.store[key] = value
        print('Detected set')

    def __getitem__(self, key):
        return self.store[key]

__setitem__ is only called when the object itself is changed:

 foo = Foo()
 foo['bar'] = 'baz'

But it is not called, for example, when:

 foo['bar'] = {}
 foo['bar']['baz'] = 'not detected inside dict'

How can I detect this kind of case, or is there some other way I should be doing this? My goal is to have a dictionary-like object that is always in-sync with a file on disk.

Makoto
  • 104,088
  • 27
  • 192
  • 230
Jimmy
  • 31
  • 1
  • Could the nested object be aware of its "parent"? You can't do this with a regular dictionary, but could with a custom mapping. – jonrsharpe May 13 '15 at 14:12
  • @stellasia that's not a great idea, see e.g. http://stackoverflow.com/q/1132941/3001761 – jonrsharpe May 13 '15 at 14:20
  • Related Mutation tracking in nested JSON structures using SQLAlchemy http://variable-scope.com/posts/mutation-tracking-in-nested-json-structures-using-sqlalchemy – Mikko Ohtamaa May 13 '15 at 14:29
  • 2
    Dict-like object which is in sync with file? Sounds like https://docs.python.org/2/library/shelve.html if you open with `writeback=True` and then regularly call `sync` you should be fine. – swenzel May 13 '15 at 14:32
  • Maybe change this `foo['bar'] = {}; foo['bar']['baz'] = 'not detected inside dict'` to this `foo['bar'] = Foo(); foo['bar']['baz'] = 'detected inside dict'`. – pavel_form May 13 '15 at 15:31

1 Answers1

1

I would suggest using shelve. I provides a persistent dictionary. Opening a file with writeback=True forces synchronization with the file:

db = shelve.open('test.db', writeback=True)

Treat it just like a dict:

>>> db['a'] = {}
>>> db['a']['x'] = 10
>>> dict(db)
{'a': {'x': 10}}

Close an re-open:

>>> db.close()
>>> db = shelve.open('test.db', writeback=True)
>>> dict(db)
{'a': {'x': 10}}

The data is still there.

Mike Müller
  • 82,630
  • 20
  • 166
  • 161
  • Note however that sync is only done when you explicitly call it (which is also done on close). If your program crashes after last change and before next sync, the data is lost. – swenzel May 13 '15 at 16:09