override a property
Steven Bethard
steven.bethard at gmail.com
Tue Oct 18 14:27:14 EDT 2005
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
More information about the Python-list
mailing list