Another way to spell __metaclass__ ?

Terry Reedy tjreedy at udel.edu
Sat Dec 14 12:56:01 EST 2002


"Gonçalo Rodrigues" <op73418 at mail.telepac.pt> wrote in message
news:1bkmvukpdke7ii1dlqq3u6o7qr957s0fdf at 4ax.com...
> Hmm... At this point I'm wondering if __metaclass__ and __class__
can
> ever be different...

The following experiment

>>> class mc(type):
...   def __init__(cls, name, bases, dct):
...     print cls.__class__
...     super(mc, cls).__init__(name, bases, dct)
...     print cls.__class__
...     cls.__class__ = type
...     print cls.__class__
...
>>> class tc: __metaclass__ = mc
...
<class '__main__.mc'>
<class '__main__.mc'>
<type 'type'>

shows

* cls.__class__ is initialized by the hidden call to the usually
hidden (staticmethod) function mc.__new__ == (inherited) test.__new__,
which gets mc (in this case) as its first parameter.  Remove the
inheritance from type and .__class__ does not get initialized
(verified, not shown).

>From Guido's essay on new-style classes: after executing the class
body, the interpreter determines its metaclass (__metaclass__ being
the first thing it looks for) and then calls its staticmethod .__new__
with that metaclass, however determined, as the first argument.

I believe setting __class__ is the only reason __new__ needs to know
what metaclass it was called on.

* cls.__class__ is rebindable (which somewhat suprised me) -- though
only to another slot-compatible object like type itself (I tried 1
first and got error message).

So yes, they can be made different -- but I  would not do this without
knowing that it had an effect other than to lie and knowing what the
effect would be (which I currently know neither of).

(I love the interactive introspection facility for learning what going
on!)

Terry J. Reedy





More information about the Python-list mailing list