properties + types, implementing meta-class desciptors elegantly?

Bengt Richter bokr at oz.net
Sat Jul 19 22:01:35 CEST 2003


On Sat, 19 Jul 2003 11:49:25 -0400, "Mike C. Fletcher" <mcfletch at rogers.com> wrote:

>Michele Simionato wrote:
>...
>
>>I agree with Bengt, from your traceback it seems you are assigning directly
>>to client.__dict__, but you cannot do that (I think because client.__dict__
>>is a dictproxy object and not a real dictionary). The right way to
>>go is via object.__setattr__ , or type.__setattr__ in the case of
>>metaclasses.
>>
>Try this to see what I'm getting at:
>
> >>> class o(object):
>...     class p( object ):
>...         def __set__( self, client, value, *args, **named ):
>...             print '__set__', self, client, value, args, named
>...             # now what do you do here to set without triggering 
>ourselves
>...             # (without having to code diff versions of the 
>descriptor class
>...             # for each possible type of client object (and for that 
>matter, just
>...             # making it possible for (meta-)types with properties 
>w/out requiring
>...             # e.g. a new dict object in each such serviced type))?.
>...             return object.__setattr__( client, "v", value)
                 client.__dict__['v'] = value
the above line should work for this example, so it must be different from
what you were doing before? Perhaps the client object before was a class?
I guess I'm not getting the big picture yet of your design intent.

Are you trying to make a  base class that has properties that can
set same-named properties in the subclass via attributes
of objects instantiated from the subclass? Or as attributes of the
subclass? Do you need the property ability to munge its arguments dynamically?
Otherwise a plain old attribute assignment to the subclass per se should install
the property for its instances, no?

>...     v = p()
>...
> >>> s = o()
> >>> s.v = 3
>
>You'll notice you go into an infinite loop.  What I'm looking for
For this example that's certainly what you'd expect. 
>(really a thinly veiled attempt to get other people to demand it from 
>Guido so he doesn't think I'm a lone crackpot ;) ) is a function/method 
>that provides the default implementation of the get/set functionality 
>*below* the level of the descriptor hooks, but high enough that it can 
>deal with the differences between classes, types, instances, and 
>instances-with-__slots__ (I realise that last one probably isn't going 
>to work, BTW).
>
>Thought of another way, it's asking for a superclass of descriptors 
>which provides this logic in such a way that, by sub-classing from them, 
>you can readily gain access to this descriptor-building functionality 
>without needing to always use it, and without introducing unwanted 
>restrictions (such as requiring a property-class initialisation).
>
>Thought of another way, it's asking for a further rationalisation of the 
>get/set hooks so that there's a lower level at which you can either 
>insert storage code *or* use the default storage code.
>
More simple examples like the above might help me understand, but I haven't
got the picture yet, I am afraid ;-)

Regards,
Bengt Richter




More information about the Python-list mailing list