Anyone know of any easy way to track changes to a dictionary object in python? I am at a high level doing crud, so I have a couple methods that handle changing a dictionary, if the dictionary changes I want to call a function to basically do an Observer/Notify.
 class MyClass(object):
     def update(self, item):
        changed = False
        if(self.my_dict.has_key(item.id)):
           self.my_dict[item.id] = item
           changed = True
        if(changed):
          self.notify()
What I am trying to avoid is all of the tracking(setting the boolean) code. Was hoping there was an easier way to track changes. This is a simple case, but there could have been more complicated logic that would result in me having to set the changed flag.
You can derive from the dict class and add a callback on any changes.  This requires to overwrite any methods that change the dictionary:
class NotifyDict(dict):
    __slots__ = ["callback"]
    def __init__(self, callback, *args, **kwargs):
        self.callback = callback
        dict.__init__(self, *args, **kwargs)
    def _wrap(method):
        def wrapper(self, *args, **kwargs):
            result = method(self, *args, **kwargs)
            self.callback()
            return result
        return wrapper
    __delitem__ = _wrap(dict.__delitem__)
    __setitem__ = _wrap(dict.__setitem__)
    clear = _wrap(dict.clear)
    pop = _wrap(dict.pop)
    popitem = _wrap(dict.popitem)
    setdefault = _wrap(dict.setdefault)
    update =  _wrap(dict.update)
                        Subclass dict and override __setitem__, making sure to call dict.__setitem__ after your stuff to ensure the item actually gets saved.
class Notifier(dict):
    def __setitem__(self, key, value):
        print 'Something is being set!'
        dict.__setitem__(self, key, value)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With