simple metaclass question

Carl Banks imbosol at vt.edu
Wed Nov 13 15:33:18 EST 2002


Michael Hudson wrote:
> Carl Banks <imbosol at vt.edu> writes:
> 
>> Thanks.  I was thinking at the C level, where objects that serve as
>> types have to have a certain fixed structure.  To create a metatype in
>> Python (not C), it would have to be an instance of a class that
>> subtypes type, right?
> 
> I don't know whether type(type(ob)) is always a subtype of type -- I
> think so -- but certainly the thing you write 
> 
> class Bob:
>    __metaclass__ = ...<---- here
> 
> doesn't have to be a subtype of type.

Of course not.  It might be useful and/or in bad style to do this:

    def makedict(name,bases,dict):
        return dict

    class whatever:
        __metaclass__ = makedict
        a = 1
        b = 2
        ...

just to create a large, built-in dictionary a little bit easier than
with the dict constructor.


> It can be handy to have a
> function here, for instance -- but if this function doesn't return a
> subtype of type, inheriting from the resulting class gets totally
> bewildering (or at least, I managed to totally bewilder myself along
> these lines).

Ok, I think a lot the difficulty is linguistic.  We're used to taking
shortcuts like saying "a is an integer," but when talking about
metaclasses, it leads to utter confusion.  We need to be explicit: "a
is an instance of integer."  (Even that is a shortcut for "a is bound
to an instance of integer," but it probably won't cause confusion for
this discussion.)

Now, obviously, the callable object given by __metaclass__ can return
any sort of object it wants, but only certain objects can serve as a
class in the normal way we think of them.  If I do this:

    class A(base):
        __metaclass__ = metafunction
        a = 1
        b = 2

    c = A(*args)

what's not clear to me is, what conditions does the object returned by
metafunction (which becomes bound to A) have to satisfy for c's type
to be A?

It seems to me that A would have to be either an instance of type, or
an instance of a subclass of type (and be callable, and return
instances of itself when called).

Now, let's assume, as is typical in metaclass programming, that
metafunction is, in fact, a class object.  Class objects, when called,
(are supposed to) return instances of themselves.  Therefore, if the
above statement is true, then the metaclass would have to be a subtype
of type,

In other words, metaclasses written in Python have to subclass type.
But, I don't think that's true of metaclasses written in C.  Since C
has control over the low-level structure of an object, C types can
create instances that have the same low-level structure as type
objects, without actually having to include "type" in it's bases.

But this opens up the possibility that a Python class could subclass
*that* object, and it needn't subclass type.  So I think the final
statement becomes: "Metaclasses written in Python have to be a
subclass of another metatype."

Ok, I think I'm clear with that, and it seems a little obvious now
that I've typed it (no pun intended :).  After taking a few hours to
fit it into my head every day, it might even become natural.


-- 
CARL BANKS



More information about the Python-list mailing list