Metaclasses are not called in subclasses. What did I wrong?

Peter Otten __peter__ at web.de
Sun Oct 29 08:22:45 CET 2006


Létez? wrote:

> I use Python 2.4.4. Please read the code below:
> 
> -----------------------------------------------------------
> from new import classobj
> 
> def mymeta(name,bases,clsdict):
>     print 'meta: %s'%name
>     return classobj(name,bases,clsdict)

mymeta is not a class.
 
> class A(object):
>     __metaclass__=mymeta

Throw in

print "A.__class__", A.__class__

here and read the sentence from the manual again: The __class__ is 'type',
so no print... side effects are to be expected below.
 
> class B(A):
>     pass
> 
> -----------------------------------------------------------
> 
> This should print
> 
> meta: A
> meta: B
> 
> when classes A and B are created. But only meta: B is missing,
> since mymeta() is not called when class B is created.
> 
> Related python documentation states that mymeta() must be called when B is
> created, since metaclasses are looked up in bases classes if not found in
> the dictionary of the class itself.
> 
>>From Python 2.4.4's manual: "Otherwise, if there is at least one base
>>class,
> its metaclass is used (this looks for a __class__ attribute first and if
> not found, uses its type)."

One way to get the output you expect:

>>> class AType(type):
...     def __init__(cls, name, bases, clsdict):
...             print "meta:", name
...
>>> class A:
...     __metaclass__ = AType
...
meta: A
>>> class B(A): pass
...
meta: B

I tried with classobj first, but that didn't work:

>>> from new import classobj
>>> class AType(classobj): pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    type 'classobj' is not an acceptable base type

Peter



More information about the Python-list mailing list