How can I make a dictionary that marks itself when it's modified?

Duncan Booth duncan.booth at invalid.invalid
Fri Jan 13 04:40:54 EST 2006


Bengt Richter wrote:

> You are right, but OTOH the OP speaks of a "flagging" the dict as
> modified. If she made e.g., "modified" a property of the dict
> subclass, then retrieving the the "modified" "flag" could dynamically
> check current state repr vs some prior state repr. Then the question
> becomes "modified w.r.t. what prior state?" 
> 
> This lets the OP ask at any time whether the dict is/has_been
> modified, but it's not a basis for e.g., a modification-event callback
> registry or such. 
> 
Good point. So the following matches what was asked for, although 
depending on the actual use pattern it may or may not match what is 
required:

---------- tracked.py -------------
import cPickle, md5
class TrackedDict(dict):
    def __init__(self, *args, **kw):
        dict.__init__(self, *args, **kw)
        self.resetModified()

    def __getstate__(self):
        return dict(self)
    def __setstate__(self, d):
        self.update(d)

    def _gethash(self):
        pickle = cPickle.dumps(self)
        hash = md5.new(pickle).digest()
        return hash
        
    @property
    def modified(self):
        return self._hash != self._gethash()

    def resetModified(self):
        self._hash = self._gethash()

if __name__=='__main__':
    d = TrackedDict(x=[])
    assert not d.modified
    d['a'] = [1, 2, 3]
    assert d.modified
    d.resetModified()
    assert not d.modified
    d['a'].append(4)
    assert d.modified
    assert d== {'x':[], 'a':[1, 2, 3, 4]}
    assert d==cPickle.loads(cPickle.dumps(d))
-----------------------------------



More information about the Python-list mailing list