override a property

Robin Becker robin at reportlab.com
Tue Oct 18 05:27:51 EDT 2005


bruno modulix wrote:
.....
> 
> Could you elaborate ? Or at least give an exemple ?
.....
in answer to Bengt & Bruno here is what I'm sort of playing with. Alex suggests 
class change as an answer, but that looks really clunky to me. I'm not sure what 
Alex means by

> A better design might be to use, instead of the builtin
> type 'property', a different custom descriptor type that is specifically
> designed for your purpose -- e.g., one with a method that instances can
> call to add or remove themselves from the set of "instances overriding
> this ``property''" and a weak-key dictionary (from the weakref module)
> mapping such instances to get/set (or get/set/del, if you need to
> specialize "attribute deletion" too) tuples of callables.

I see it's clear how to modify the behaviour of the descriptor instance, but is 
he saying I need to mess with the descriptor magic methods so they know what 
applies to each instance?


## 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


-- 
Robin Becker




More information about the Python-list mailing list