Шаблон прослушивателя свойств Python

Кто-нибудь знает какой-либо простой способ отслеживать изменения объекта словаря в python? Я на высоком уровне делаю crud, поэтому у меня есть несколько методов, которые обрабатывают изменение словаря, если словарь изменяется, я хочу вызвать функцию, чтобы в основном выполнять 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()

То, что я пытаюсь избежать, - это все отслеживание (установка логического) кода. Надеюсь, что есть более простой способ отслеживать изменения. Это простой случай, но может быть более сложная логика, которая привела бы к тому, что мне пришлось бы установить измененный флаг.

Ответ 1

Вы можете получить класс dict и добавить обратный вызов при любых изменениях. Для этого необходимо перезаписать любые методы, которые меняют словарь:

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)

Ответ 2

Подкласс dict и переопределить __setitem__, убедившись, что вы вызываете dict.__setitem__ после того, как ваши вещи будут сохранены.

class Notifier(dict):
    def __setitem__(self, key, value):
        print 'Something is being set!'
        dict.__setitem__(self, key, value)