Robin Becker wrote: > ## my silly example > class ObserverProperty(property): > def __init__(self,name,observers=None,validator=None): > self._name = name > self._observers = observers or [] > self._validator = validator or (lambda x: x) > self._pName = '_' + name > property.__init__(self, > fset=lambda inst, value: self.__notify_fset(inst,value), > ) > > def __notify_fset(self,inst,value): > value = self._validator(value) > for obs in self._observers: > obs(inst,self._pName,value) > inst.__dict__[self._pName] = value > > def add(self,obs): > self._observers.append(obs) > > def obs0(inst,pName,value): > print 'obs0', inst, pName, value > > def obs1(inst,pName,value): > print 'obs1', inst, pName, value > > class A(object): > x = ObserverProperty('x') > > a=A() > A.x.add(obs0) > > a.x = 3 > > b = A() > b.x = 4 > > #I wish I could get b to use obs1 instead of obs0 > #without doing the following > class B(A): > x = ObserverProperty('x',observers=[obs1]) > > b.__class__ = B > > b.x = 7
Can you add the object to be observed as another parameter to the add method? py> class ObservableProperty(property): ... def __init__(self, *args, **kwargs): ... super(ObservableProperty, self).__init__(*args, **kwargs) ... self._observers = {} ... def __set__(self, obj, value): ... super(ObservableProperty, self).__set__(obj, value) ... for observer in self._observers.get(obj, []): ... observer(obj) ... def add(self, obj, observer): ... self._observers.setdefault(obj, []).append(observer) ... py> class A(object): ... def _getx(self): ... return self._x ... def _setx(self, value): ... self._x = value ... x = ObservableProperty(_getx, _setx) ... py> def obs1(obj): ... print 'obs1:', obj.x ... py> def obs2(obj): ... print 'obs2:', obj.x ... py> a = A() py> a.x = 3 py> A.x.add(a, obs1) py> a.x = 4 obs1: 4 py> A.x.add(a, obs2) py> a.x = 5 obs1: 5 obs2: 5 py> b = A() py> b.x = 6 py> A.x.add(b, obs2) py> b.x = 7 obs2: 7 Probably "self._observers" should use some sort of weakref dict instead of a regular dict, but hopefully the idea is clear. STeVe -- http://mail.python.org/mailman/listinfo/python-list