[Python-Dev] assymetry in descriptor behavior
David Abrahams
dave@boost-consulting.com
Sun, 23 Feb 2003 19:46:25 -0500
Guido van Rossum <guido@python.org> writes:
>> I notice that Python supports this sort of dual access for reading
>> attributes and calling static functions, but getting that behavior for
>> mutable attributes seems unreasonably difficult: I need a property in
>> the metaclass *and* in the class.
>
> I disagree that it is *unreasonably* difficult. Given that Python
> tries to do with a single notation ('.') where C++ has two notations
> ('.' and '::') to disambiguate cases
FWIW, it doesn't disambiguate anything:
class C
{
static int x;
};
C c;
int y = C::x;
int z = c.x;
The compiler already knows which of 'C' and 'c' is a typename and
which is an object. Maybe it's just a pointless syntax difference...
> not to mention declarations, I think it is reasonable that this
> unusual case requires a little more effort; you should be glad that
> it's possible at all. :-)
My heart is full of gladness!
>> 1. To throw out a straw-man suggestion, what about adding an
>> additional protocol __set2__ which, if found, will be called
>> instead of __set__ both for reading _and_ writing attributes on the
>> class?
>
> Let me throw out this straw-man right away: I'm not excited about
> this. You can write a metaclass that implements this generically
> though.
I considered these two options:
option 1:
introduce a separate metaclass for every wrapped class so that we
have a place to stick a property object.
option 1a:
only do this if the user supplies a special extra template
parameter to the class_<...> declaration
option 2:
Implement a special property type which allows us to easily
identify property attributes which correspond to Boost.Python static
data members
Implement a special __setattr__ in the Boost.Python metaclass which
looks up the attribute on the class to see if it has this special
type; if so, it is called, and otherwise the default __setattr__
behavior takes effect.
I was going to go with option 1. Are you suggesting option 2?
>> 2. What are the optional type=None arguments for? It seems as though
>> only the middle argument (obj) is ever None. I just copied this
>> protocol out of descrintro.html
>
> Only __get__ has both obj and type as arguments; __set__ has obj and
> value, __delete__ only obj.
>
> __get__ has obj and type because it can be used for instance and class
> attribute access. When called for a class, obj is None because it is
> unavailable; but when called for an instance, type is set to obj's
> class, for the convenience of descriptors that aren't interested in
> the instance (like staticmethod and classmethod).
Yes, but type is always non-None, it seems. Look at descrintro.html
again. It says:
Example: coding super in Python.
As an illustration of the power of the new system, here's a fully
functional implementation of the super() built-in class in pure
Python. This may also help clarify the semantics of super() by
spelling out the search in ample detail. The print statement at the
bottom of the following code prints "DCBA".
class Super(object):
def __init__(self, type, obj=None):
self.__type__ = type
self.__obj__ = obj
def __get__(self, obj, type=None):
^^^^^^^^^
if self.__obj__ is None and obj is not None:
return Super(self.__type__, obj)
else:
return self
Also, PEP 252 says:
- __get__(): a function callable with one or two arguments that
retrieves the attribute value from an object.
What's that about? Does __get__ ever get called with just one
argument (excluding self)? If so, when?
>> 3. Is there documentation for __delete__ anywhere?
>
> Apparently not, but it's easy to guess what it does if you know
> __getattr__, __setattr__ and __delattr__. It's __delete__ and not
> __del__ because __del__ is already taken. In an early alpha release
> it was actually __del__, but that didn't work very well. :-)
It's easy enough to guess what it does by instrumenting it, too.
However, it's been out in a released Python for several versions now
and I get tired of guessing every time I have to write a new one of
these ;-). I think it's time there were some official docs.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com