Robin Becker wrote: > Kay Schluehr wrote: > > Robin Becker wrote: > > > > > >>I thought that methods were always overridable. > >>In this case the lookup on the > >>class changes the behaviour of the one and only property. > > > > > > How can something be made overridable that is actually overridable? I > > didn't know how to better express the broken polymorphism of Pythons > > properties than by stating it as a pleonasm about the used get and set > > methods. This way a property don't ever have to be redefined in > > subclasses if get_x, set_x etc. are changed. > > > > Kay > > > > well I guess that's the ambiguity of human language. Clearly when I > assign to a normal attribute I am changing its value; assigning to a > property or descriptor does something that is not so obvious. Changing > the behaviour of such an attribute could be done by inheritance as > suggested. The new class has overridden the property. When I want to do > that on an instance I have first to create a mutable version of the > descriptor where the mutability is on the instance not the class. I call > the action of changing the base descriptor behaviour 'overriding', but > perhaps that's not the correct word. What do you suggest? > -- > Robin Becker
I would suggest to take a step back and start with Raymond Hettingers descriptor definition: "In general, a descriptor is an object attribute with "binding behavior", one whose attribute access has been overridden by methods in the descriptor protocol. Those methods are __get__, __set__, and __delete__. If any of those methods are defined for an object, it is said to be a descriptor." http://users.rcn.com/python/download/Descriptor.htm The definition is a little confusing since we have to identify the descriptor object that implements one of the descriptor methods __get__, __set__ and __del__ with an object attribute that is assigned by the descriptor ( as object not attribute ). Otherwise we can assert that a descriptor becomes effective only if it is used as an object attribute. The meaning / essence of a descriptor is to assign attributes by a descriptor to alter binding behaviour but it's essentially an object that can be handled quite differently. To make the destinction clear I will talk about "descripted" attributes. Now we can talk unambigously about "overriding" the descriptor by means of overriding the descriptor methods in subclasses. In case of "properties" we pass certain functions into property() that will be wrapped into descriptor methods. Thereby property() is itself a descriptor. If we use methods of the class where the descripted attribute is defined, overriding has no effect on the descriptor. The inheritance hierarchies of descriptors and classes that define descripted attributes do not correspond. One way of establishing a pseudo-correspondence I've already presented. But maybe one can do it better without decorators? Remember that property() is a descriptor factory and there is no intrinsic need to pass functions into a factory function. Why not passing strings that are names of methods? For brevity only __get__ should be defined here: class described_by(object): def __init__(self, fget=""): assert isinstance(fget, str) self.fget = fget def __get__(self, obj, objtype=None): if obj is None: return self if self.fget is None: raise AttributeError, "unreadable attribute" return getattr(obj.__class__, self.fget)(obj) class A(object): def __init__(self, x): self._x = x def get_x(self): return self._x x = described_by("get_x") class B(A): def get_x(self): return self._x**2 >>> a = A(7) >>> a.x 7 >>> b = B(7) >>> b.x 49 Regards, Kay -- http://mail.python.org/mailman/listinfo/python-list