问题 Python属性更改侦听器模式


任何人都知道在python中跟踪字典对象更改的任何简单方法吗?我处于高水平,因此我有几个方法可以处理更改字典,如果字典更改我想调用一个函数来基本上执行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()

我想避免的是所有跟踪(设置布尔值)代码。希望有一种更简单的方法来跟踪变化。这是一个简单的案例,但可能有更复杂的逻辑导致我必须设置更改的标志。


9179
2018-03-03 21:04


起源

if item.id in self.my_dict { self.my_dict[item.id] = item; self.notify() }? (请原谅支持和分号,但评论吃断线)


答案:


你可以从中得到 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)

12
2018-03-03 21:21



这项工作,只需要小心参考类型...... - Nix
@Nix - 小心如何,为什么?你能解释一下吗? - Vijay Varadan
@VijayVaradan这只适用于第一级属性更改。所以,如果我有一个 obj 它有一个 dict 我修改字典,改变不会被拿起。它只会捡起来 obj.xyz, 有道理? - Nix


子类 dict 和覆盖 __setitem__,一定要打电话 dict.__setitem__ 在你的东西后,以确保项目实际上得到保存。

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

0
2018-03-03 21:20



你会怎么用 Notifier 然后?我有一个我想知道的对象 self.__member 价值变化?是 Notifier 然后封装在那个对象中?你能扩展一下如何使用它吗? - IAbstract