Add Properties to Instances?
bokr at oz.net
Mon Mar 14 11:21:47 CET 2005
On 14 Mar 2005 01:19:23 -0800, "Martin Miller" <ggrp1.20.martineau at dfgh.net> wrote:
>In answer to my question about instance properties not working, Bengt
>Richter suggest using:
>> > >>> class InstProp(object):
>> > ... def __getattribute__(self, attr):
>> > ... p = object.__getattribute__(self, attr)
>> > ... if isinstance(p, property): return p.__get__(self)
>> > ... return p
>and more generally for any descriptor object:
>> >>> class InstProp(object):
>> ... def __getattribute__(self, attr):
>> ... p = object.__getattribute__(self, attr)
>> ... if hasattr(p, '__get__'): return p.__get__(self,
>> ... return p
>Both the above makes the '__get__' method of any property attributes of
>the instance to be used. However, it does not cause attempts to be made
>to access their "__set__' methods when assigning to them (which should
>fail in my case because my properties don't have such a method because
>they are read-only).
>Just overriding '__getattribute__' alone is insufficent to make
>instance property/descriptor attributes fully function. To do so also
>requires overriding the __setattr__ method so it checks for a '__set__'
>method and then uses it if one is found (or delegates it to
>object.__setattr__ if not).
>Similarily, an override for '__delattr__' would also be need for
>complete property functionality, I believe.
As I said in my first post,
If you want robust writeable and/or deleteable properties, you will have
to do a little more work, but it can be done.
I'm still leaving it as an exercise ;-)
>For just making instance attributes read-only, it seems to be that the
>simplist solution would be to override __setattr__ and make it check to
>see if the attribute is write protected or not, which is really all I
>need for the specific task I'm trying to accomplish (which is
>esstentially what Jeremy Bowers said in his reply).
>What still puzzles me, though, is why all the above to make properties
>work on instances is necessary in the first place. It's certainly not
>clear (to me) from what is said in the How-to at:
>I suspect that it may be simply a performance issue, in other words, it
>was considered too slow to check for instance property/discriptors --
>although *why* is not clear to me.
I suspect the desired semantics re precedence have evolved to make normal
programs easily implementable, and that probably drove the implementation:
For objects, the machinery is in object.__getattribute__ which transforms
b.x into type(b).__dict__['x'].__get__(b, type(b)).
The implementation works through a precedence chain that gives (my added [1,2,3])
 data descriptors priority over instance variables,
 instance variables priority over non-data descriptors,
 and assigns lowest priority to __getattr__ if provided.
The full C implementation can be found in PyObject_GenericGetAttr() in Objects/object.c.
More information about the Python-list