Per instance descriptors ?

bruno at modulix onurb at xiludom.gro
Thu Mar 23 10:28:39 CET 2006

Steven Bethard wrote:
> bruno at modulix wrote:
>> Hi
>> I'm currently playing with some (possibly weird...) code, and I'd have a
>> use for per-instance descriptors, 

>> class MyClass2(MyClass1):
>>     def __getattribute__(self, key):
>>         v = MyClass1.__getattribute__(self, key)
>>         if hasattr(v, '__get__'):
>>             return v.__get__(self, self.__class__)
>>         return v
>> And it *seems* to work just fine:
>> mc2 = MyClass2(bar='foo')
>> mc2.baaz
>> ->  'foo'
>> Now the question: is there any obvious (or non-obvious) drawback with
>> this approach ?
> Don't know if this matters, but if you override __getattribute__, you'll
> slow down all attribute accesses to this object.

Yes, I know, but this shouldn't be a major annoyance here.

>  If this matters, you
> could write something like:
>     class MyClass(object):
>         def __init__(self, bar=None):
>             if bar is not None:
>        = bar
>         def __getattr__(self, name):
>             if name == 'baaz':
>                 return
>             elif name == 'bar':
>                 return 'no bar'

Don't focus on the dummy example I gave - the real descriptors are doing
something a bit less stupid !-)

> Could you explain again why you don't want baaz to be a class-level
> attribute?

Because the class is a decorator for many controller functions, and each
controller function will need it's own set of descriptors, so I don't
want to mess with the class.

Think of the decorator as a prototype, each controller function
customizing it according to it's need  - this customisation including
the decorator instance attaching descriptors and methods to itself
according to parameters passed at __init__ time. The decorator instance
also passes itself as first arg to the controller function - which then
practically become an instance method too.

Don't tell me, I know this is a somewhat weird architecture, and it
could mostly be done with more conventional subclassing. BTW, this was
how a first implementation worked, and it required almost twice more
code than the new one I'm experimenting, without being half as flexible.

As I said, it's mostly syntactic sugar, but what, I'm lazy enough to
spend time on writing code that will allow me to write less code in the
end !-)

bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb at xiludom.gro'.split('@')])"

More information about the Python-list mailing list