properties + types, implementing meta-class desciptors elegantly?
Aahz
aahz at pythoncraft.com
Fri Jul 25 19:48:11 EDT 2003
In article <mailman.1058713111.11669.python-list at python.org>,
Mike C. Fletcher <mcfletch at rogers.com> wrote:
>Aahz wrote:
>>In article <mailman.1058654317.6488.python-list at python.org>,
>>Mike C. Fletcher <mcfletch at rogers.com> wrote:
>>>
>>> * finally, stores the value
>>> o tries to do what would have been done if there were no
>>> descriptor (with the new, coerced value)
>>> o does *not* create new names in the object's namespace (all
>>> names are documented w/ descriptors, there's not a lot of
>>> '_' prefixed names cluttering the namespace)
>>> o does *not* require a new dictionary/storage-object attribute
>>> for the object (the descriptor works like any other
>>> descriptor, a *stand-alone* object that replaces a regular
>>> attribute)
>>
>>But this is a recipe for name clashes. If you follow the first bullet,
>>it's a normal attribute, but everything else says you want a property.
>>Properties are themselves objects that are attached to names in an
>>object. You can't have the same name bound to two different objects.
>
>It's true that:
>
> * your class has a namespace, and there are objects stored in that
> namespace
> o the objects stored in that namespace often are descriptors
> o they are available to the instances which do not shadow them
> (as I said, I can deal with this, and it's cleaner anyway).
> + if they are descriptors, they modify instance access
> to attributes
That's technically inaccurate as phrased. First of all, not all
descriptors get activated through attribute access, only data
descriptors do. Data descriptors are descriptors that define a ``set``
attribute (which is essentially a method of the descriptor object).
Secondly, it muddies understanding to say that the descriptor modifies
access to attributes, as if the descriptor is a proxy for an attribute.
Data descriptors *replace* attributes, and if you want to store a value,
it's your responsibility to determine where that value is stored (and
how to retrieve it).
> * the metaclass instance's property *values* would be stored in the
> metaclass instance's dictionary, just as is normally done (the
> metaclass' property *descriptors* would be stored in the
> metaclass' dictionary), there's no new conflicts created here,
> everything just works like it does now, a lookup would look
> something like this:
>
> >>> x.y
>x doesn't have a __getattribute__, so see if it has a descriptor for 'y'
Actually, x is the *last* object checked, and __getattribute__() is
never called on instances.
> get type(x).y
>
> type(x) doesn't have a __getattribute__, so see if it has a
> descriptor for 'y'
>
> get type(type(x)).y -> this is just a simple descriptor, as
> there's no higher-level descriptor, has a __get__ method,
> calls it to retrieve type(x).y
That should be type(type(x).y), I think. (I'm not testing this in
code.)
> returns the currently stored entry 'y' in type(x)'s dictionary,
> which happens to be a descriptor
>
> has type(x).y, a descriptor with a __get__ method, calls it, gets
> back value stored in instance's dictionary
That's correct if type(x).y is a data descriptor; other types of
descriptors do get overridden by the instance.
>You wind up with some names that are not available for use *as
>properties* on instances *iff* you set a simple value for the properties
>of the meta-class instance, but you solve that the regular way, by
>making the value stored by the meta-class instance's property a
>descriptor, rather than a simple value. That's just the way classes
>work. Yes, it's a "name clash", but everything in classes/instances is
>name clashes <shrug>.
Instances don't have properties, only types do. A metaclass is "just" a
class that creates classes (which are themselves types with new-style
classes). Problems only show up when you want to access class behavior
*through* a class instance.
>Not a problem I can see in the problem I outlined just yet, there's
>still no low-level value-setting mechanism exposed,
The point is that there's no low-level value. You always have to
explicitly specify the name and namespace when you use properties.
--
Aahz (aahz at pythoncraft.com) <*> http://www.pythoncraft.com/
This is Python. We don't care much about theory, except where it intersects
with useful practice. --Aahz
More information about the Python-list
mailing list