Add Properties to Instances?

Bengt Richter 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,
>type(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:
>>
>http://users.rcn.com/python/download/Descriptor.htm#invoking-descriptors
>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])

[1] data descriptors priority over instance variables,
[2] instance variables priority over non-data descriptors,
[3] and assigns lowest priority to __getattr__ if provided.

The full C implementation can be found in PyObject_GenericGetAttr() in Objects/object.c.
"""

Regards,
Bengt Richter



More information about the Python-list mailing list