properties + types, implementing meta-class desciptors elegantly?

Mike C. Fletcher mcfletch at rogers.com
Tue Jul 22 06:30:12 CEST 2003


Michele Simionato wrote:

>"Mike C. Fletcher" <mcfletch at rogers.com> wrote in message news:<mailman.1058717611.28555.python-list at python.org>...
>  
>
...

>>You are aware that you have just created a class-attribute, rather than 
>>an instance attribute?  The property/descriptor object exists within the 
>>class 'o' namespace, not the instance namespace.  Try creating two 
>>instances of your o class and setting v on both of them.  There is one 
>>'p' instance "self" to which you are assigning/retrieving an attribute 
>>for all instances of o.  Creating class variables is certainly a valid 
>>use for descriptors, but I'm not sure if that's really what you were 
>>trying to do.
>>    
>>
>
>I have just copied your code, I thought you wanted a class attribute.
>
I should have been more precise.  Your value is stored in the 
descriptor, so it is not a per-class attribute, it is an attribute 
stored in one place for *all* instances of all sub-classes of the 
defined class, it is not a property of the class, but an effectively 
static variable in the class definition.  That is, each instance 
modifies the one copy of the value, regardless of the instance' class.  
I'm looking for a meta-property, a property of a class, rather than a 
property of a class-instance.  Changing an instance's value for that 
name shouldn't affect this value.  Changing the meta-property value 
should only occur when you do setattr( cls, key, value ), and should 
store the value in the *particular* concrete class having the value set, 
not on some ancestor of that class, just as if you were to do setattr( 
cls, key, value) without any meta-descriptor being present.

>It is is trivial to do the same for instance attributes:
>
>class o(object):
>    class p( object ): # descriptor class
>        def __set__( self, client, value, *args, **named ):
>            print '__set__', self, client, value, args, named
>            self.value=value
>        def __get__(self,obj,cls):
>            return self.value
>
>    def __init__(self):
>        self.v = self.p()
>
>I understand that you aware of this, but you don't like it. Still I
>do not understand why do you feel it to be ugly and/or inelegant. It
>seems to me quite idiomatic.
>  
>
It's just not what I'm trying to do (create active properties on 
meta-classes).  It's a perfectly fine way to create class-static 
variables shared among a hierarchy of instance objects.

>Yes, I understand you want to be able to set class dictionaries just
>as object dictionaries, bypassing descriptors. Still, I am not sure
>if this would be a good idea.
>
Well, just to clean up the descriptor API it's probably worth it IMO, 
but I only seem to have Michael to back me up on that so far :) .  
There's a missing level of functionality/hooks that haven't been exposed 
and should be exposed to allow more general & orthogonal operation of 
descriptor code. 

Basically, it should be possible to mimic the built-in behaviour of 
setattr/getattr w/out resorting to horrific hacks just to get that 
behaviour.  In other words, it should be possible to interpose an 
operation in the descriptor-processing stream in much the same way that 
super() allows for co-operative mix-in classes to inter-operate by 
saying 'okay, do what would have been done if this "filter" method 
didn't exist'.

>Elegance is in the eye of the beholder ;)
>
Indeed.

>Good luck with your project,
>
Thanks.  Enjoy,
Mike







More information about the Python-list mailing list