468,550 Members | 1,692 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,550 developers. It's quick & easy.

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

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)

class A(object):
__metaclass__=mymeta

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)."

Thanks for your help.

Viktor

Oct 29 '06 #1
2 1323
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
Oct 29 '06 #2
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)

class A(object):
__metaclass__=mymeta

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)."
Peter already explained that when __metaclass__ is not directly defined in the
class body, it's not used as the metaclass, but the class of the first base
class is.

This is an inconsistency IMHO, since Python normally respects inherited
attributes just like those defined in the class itself.

But well, you can live with it :)

Georg
Oct 29 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Stephan Diehl | last post: by
3 posts views Thread by Mike C. Fletcher | last post: by
2 posts views Thread by Santiago Aguiar | last post: by
27 posts views Thread by Michele Simionato | last post: by
4 posts views Thread by Michael Sparks | last post: by
1 post views Thread by Hartmut Goebel | last post: by
8 posts views Thread by Jan-Ole Esleben | last post: by
4 posts views Thread by Laszlo Nagy | last post: by
1 post views Thread by UniDue | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.