[Zope3-dev] Re: Interface support in Python? (was Re: [Zope3-dev]
Proposal: Improving on __implements__)
Jim Fulton
jim@zope.com
Thu, 23 Jan 2003 07:25:55 -0500
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?
I'm sorry, I really don't want to think about meta-meta classes.
> getattr(instance, 'foo')
> gets me the foo of the instance
yes
> or if there is none, the foo of the class
yes
> or if there is none, the foo of the metaclass,
no
> or if there is none, the foo of the meta-metaclass,
don't care. :) (But I'd guess no)
> or if there is none, a KeyError
No, AttributeError
> getattr(cls, 'foo')
> gets me the foo of the class
yes
> or if there is none, the foo of the metaclass,
yes
> or if there is none, the foo of the meta-metaclass,
don't care. :) (But I'd guess no)
> or if there is none, a KeyError
No, AttributeError
> getattr(metacls, 'foo')
> gets me the foo of the metaclass,
yes
> or if there is none, the foo of the meta-metaclass,
don't care. :) (But I'd guess yes)
> or if there is none, a KeyError
No, AttributeError
You made me perform the followeing experiment.
I wrote the script:
-------------------------------------------
class dualattr(object):
def __init__(self, ival, cval):
self.ival = ival
self.cval = cval
def __get__(self, inst, class_):
if inst is None:
return self.cval
else:
return self.ival
class m(type):
mm = 'mm'
mc = 'mc'
mi = 'mi'
x = dualattr("cx", "mx")
y = dualattr("cy", "my")
class c:
__metaclass__ = m
cc = 'cc'
ci = 'ci'
mc = 'cmc'
mi = 'cmi'
y = dualattr("iy", "cy")
z = dualattr("iz", "cz")
i = c()
i.ii = 'ii'
i.ci = 'ici'
i.mi = 'imi'
print 'i.mm', getattr(i, 'mm' ,'AttributeError')
print 'i.mc', getattr(i, 'mc' ,'AttributeError')
print 'i.mi', getattr(i, 'mi' ,'AttributeError')
print 'i.cc', getattr(i, 'cc' ,'AttributeError')
print 'i.ci', getattr(i, 'ci' ,'AttributeError')
print 'i.ii', getattr(i, 'ii' ,'AttributeError')
print 'i.x', getattr(i, 'x' ,'AttributeError')
print 'i.y', getattr(i, 'y' ,'AttributeError')
print 'i.z', getattr(i, 'z' ,'AttributeError')
print
print 'c.mm', getattr(c, 'mm' ,'AttributeError')
print 'c.mc', getattr(c, 'mc' ,'AttributeError')
print 'c.mi', getattr(c, 'mi' ,'AttributeError')
print 'c.cc', getattr(c, 'cc' ,'AttributeError')
print 'c.ci', getattr(c, 'ci' ,'AttributeError')
print 'c.x', getattr(c, 'x' ,'AttributeError')
print 'c.y', getattr(c, 'y' ,'AttributeError')
print 'c.z', getattr(c, 'z' ,'AttributeError')
print
print 'm.mm', getattr(m, 'mm' ,'AttributeError')
print 'm.mc', getattr(m, 'mc' ,'AttributeError')
print 'm.mi', getattr(m, 'mi' ,'AttributeError')
print 'm.x', getattr(m, 'x' ,'AttributeError')
print 'm.y', getattr(m, 'y' ,'AttributeError')
print
i.mm
-------------------------------------------
i.mm AttributeError
i.mc cmc
i.mi imi
i.cc cc
i.ci ici
i.ii ii
i.x AttributeError
i.y iy
i.z iz
c.mm mm
c.mc cmc
c.mi cmi
c.cc cc
c.ci ci
c.x cx
c.y cy
c.z cz
m.mm mm
m.mc mc
m.mi mi
m.x mx
m.y my
Traceback (most recent call last):
File "t.py", line 69, in ?
i.mm
AttributeError: 'c' object has no attribute 'mm'
-------------------------------------------
which seems pretty reasonable.
Note that the dualattr descriptor illustrates how the __implements__ descriptor
would work. With your proposal, given a custom meta class, there would be two
ways of saying what the interface if a class is. You use "implements" in the
meta class, or you can say "classImplements" in the class.
> Maybe a change in the way getattr and metaclasses work could accompany a
> proposal to get interfaces into Python?
I don't think this is necessary.
Jim
--
Jim Fulton mailto:jim@zope.com Python Powered!
CTO (888) 344-4332 http://www.python.org
Zope Corporation http://www.zope.com http://www.zope.org