[Zope3-dev] Re: Interface support in Python? (was Re:
[Zope3-dev] Proposal: Improving on __implements__)
Phillip J. Eby
pje@telecommunity.com
Thu, 23 Jan 2003 09:23:22 -0500
At 11:17 AM 1/23/03 +0200, Steve Alexander wrote:
>> You can't use the class dictionary's '__implements__' entry to hold
>> the value, because that entry needs to be saved for the descriptor to
>> say what the class provides to *its* instances. So you have to come up
>> with another name for the entry to hold the value. Only, you can't use
>> the same name for both instances and classes, because there might be
>> another meta-level that needs to store an assertion for *its* instances...
>
>getattr seems to be a bit over-overloaded in this example.
>
>If I have an instance, its class, its metaclass, and its meta-metaclass,
>is the following true?
>
> getattr(instance, 'foo')
> gets me the foo of the instance
> or if there is none, the foo of the class
> or if there is none, the foo of the metaclass,
> or if there is none, the foo of the meta-metaclass,
> or if there is none, a KeyError
No. This stops at the foo of the class. Also, if we're talking about a
new-style class, then the class is first checked for a 'foo' data
descriptor, and if present, that is called without looking at the instance
dictionary. If 'foo' is in the class, but not a data descriptor, the
instance dictionary is checked, with fall back to the non-data descriptor
in the class.
> getattr(cls, 'foo')
> gets me the foo of the class
> or if there is none, the foo of the metaclass,
> or if there is none, the foo of the meta-metaclass,
> or if there is none, a KeyError
Nope. Stops at the foo of the metaclass. And actually, it works the same
as above... the metaclass is checked for 'foo' first, if it has a data
descriptor, that's used, otherwise fall back to the class dictionary and
base class dictionaries in __mro__ order, then use a metaclass non-data
descriptor, if present.
> getattr(metacls, 'foo')
> gets me the foo of the metaclass,
> or if there is none, the foo of the meta-metaclass,
> or if there is none, a KeyError
>
> getattr(metacls, 'foo')
> gets me the foo of the meta-metaclass,
> or if there is none, a KeyError
Pretty much, only it's AttributeError.
>Maybe a change in the way getattr and metaclasses work could accompany a
>proposal to get interfaces into Python?
Actually, Python works just fine. It's just that trying to have a thing
that looks the same no matter what meta-level you're at gets tricky. At
any *one* level, or even two, you can have some clarity.
The tangling is at the level of "class attribute" (a value defined in a
class) and "metaclass instance attribute" (defined in the metaclass to be
an attribute of the class). My experience has been that it's better to use
the latter than the former, when expressing data about a class. In other
words, define a metaclass with a "data descriptor", rather than try to
declare such information in the class.