Another way to spell __metaclass__ ?

Gonçalo Rodrigues op73418 at mail.telepac.pt
Sat Dec 14 11:02:58 EST 2002


On 13 Dec 2002 18:56:43 GMT, bokr at oz.net (Bengt Richter) wrote:

>On Fri, 13 Dec 2002 15:46:13 +0000, Gonçalo Rodrigues <op73418 at mail.telepac.pt> wrote:
>
>>On 13 Dec 2002 06:08:42 GMT, bokr at oz.net (Bengt Richter) wrote:
>>
>>>
>>>I must confess there is something that bothers me about __metaclass__ as
>>>an impementation of metaclass functionality. It strikes me more as a
>>>class transmogrification hook with a debug/trace flavor than a clear expression
>>>of the relationship between two classes, one of which produces the other
>>>as an instance.
>>>
>>>I.e., to me, the hallmark of a metaclass is that it produces another class when
>>>instantiated (normally with variations based on conditions or parameters, or why
>>>do it).
>>
>>At the risk of having completely missed the point, your gripe with
>>__metaclass__ is of a purely syntactic nature. A metaclass *is* a class
>Not quite just syntactic (and sorry if it sounded like a "gripe" ;-)

Bad choice of words. If we compare choosing words with shooting people
then I am a drunken gunman with delirium tremens.

>
>>whose instances are classes themselves, except currently there is simply
>>no way to attach to a class statement information specifying the
>>metaclass other than the __metaclass__ thingy.
>>
>Well, <devil's advocate> why do you need such an "attachment?" </da>
>(E.g., my example was meant to show a way of associating the "attached"
>elements without using __metaclass__).
>

Let me answer with another question: How would you propose to specify
*in a class statement* that the class object has a class different from
type?

>I was exploring the idea of not having an "attachment" arrow from
>a class to its metaclass, but instead expressing it as an arrow that points
>in the other direction, or creates the arrow of association dynamically by
>ordering of function arguments.

Right. 

The first example of Metaclass I've done was a Field metaclass whose
instances were the finite rings Z_n of integers mod n (I've posted it in
the ActiveState cookbook if you want to have a look at it). As in your
case, there is no __metaclass__ because the classes have to be created
at run time anyway. But creating classes at run time is not something
that is done every day. It is probably much more common to create a
class with a class statement (at "compile time" so to speak) - and if
you want the *resulting* class object to have a metaclass other than
type you just attach the __metaclass__ thingie. But the processes are
not really different.

And in your (and mine) example the metaclass is there alright. It's the
__class__ attribute. 

In fact the following example shows that __class__ and __metaclass__ are
the same thing:

>>> class MyMetaclass(type):
... 	def __init__(cls, name, bases, dct):
... 		super(MyMetaclass, cls).__init__(name, bases, dct)
... 		
>>> print MyMetaclass, MyMetaclass.__class__
<class '__main__.MyMetaclass'> <type 'type'>
>>> class test(object):
... 	__metaclass__ = MyMetaclass
... 	def __init__(self):
... 		super(test, self).__init__()
... 		
>>> print test.__class__, test.__metaclass__
<class '__main__.MyMetaclass'> <class '__main__.MyMetaclass'>
>>> 

Hmm... At this point I'm wondering if __metaclass__ and __class__ can
ever be different... I haven't looked at the type code and I'm too tired
to think about it, but if it can ever be it would be a *really strange*
beast.

>
>ISTM a metaclass is not the same concept as a base class, (though they can interact).
>Inheritance of e.g. class Base by another is specified in the inheritor source, e.g.,
>class Inheritor(Base), and the inheritor modifies and/or extends the base, and the
>modifying entity specifies (via base list) the prototype that it is modifying.
>
>In the case of a metaclass, it it doing the modifying, but it does not specify the
>prototype info that it is modifying. Instead, the prototype class info specifies its
>modifier by unique name (i.e., using __metaclass__ = unique name).
>
>Either way, there is a composition of elements, but it's expressed differently.
>
>To me, a class source definition is a spec for creating a class entity which
>can retrieve and/or create elements and compose them into a composite entity
>when called upon to do so (i.e., class instantiation).
>
>Note that the class source specifies directly or indirectly all the things that
>it's going to be composing together. And the action of composing is triggered
>by calling the defined class object as a function.
>
>Now contrast a metaclass. ISTM, if a metaclass is a class, the same abstract
>description should apply. But what does __metaclass__ do? A class containing
>a __metaclass__ line is still effectively an argument to a composition function,
>yet somehow the argument specifies the function (and thereby excludes itself
>from being and argument to another compatible composition function).
>
>I.e., instead of having a (meta)class source definition which specifies elements
>to be composed, one of those elements is specifying the (meta)class! That's like a base
>class specifying a deriving class, ISTM. I.e., the arrow is points weirdly, IMO.
>And the action of composing is not triggered by an explicit call of the (meta)class
>object as a function, but instead that call happens at a certain phase of the
>execution of the definition of one of the composition elements (i.e., when the
>execution of the defintion of the class containing __metaclass__ finishes).

I believe you are making things more complicated than they (already) are
- the separation is artificial. The gist as I see it, is that a class
statement is doing double duty: it is specifying the "prototype" for its
instances *and at the same time* it has to somehow specify the
(meta)class of the resulting class object. The bad syntax just makes
things more awkward.

>
>>The same problem happens for example when you want to declare a static
>I hope I have been able to express something that is not "the same problem" ;-)
>
>>method, you have to use something like
>>
>>def mystaticmethod(*args, **kwargs):
>>    <whatever>
>>
>>mystaticmethod = staticmethod(mystaticmethod)
>Somehow this doesn't bother me at all compared to __metaclass__ ;-)
>
>>
>>It would be much better if some kind of pseudo keyword would be
>>introduced, e.g.
>>
>>def static mystaticmethod(*args, **kwargs):
>>    <whatever>
>>
>>[most interesting stuff snipped]
>>
>>Unfortunately, as far as I remember, such syntactic sweetening is not
>>scheduled to happen in the next 2.3.
>
>ISTM there is more involved than syntactic sweetening ;-)

What does ISTM stand for?

>
>Regards,
>Bengt Richter

With my best regards,
G. Rodrigues



More information about the Python-list mailing list