Reputation: 1226
In the following code:
class Meta(type):
def __new__(cls, name, bases, attrs):
print(name)
return type(name, bases, attrs)
class A(object, metaclass=Meta):
def do_complex_task(self):
pass
class B(A):
def do_minor_task(self):
pass
I'd expect to see both A
and B
get printed, but I see that the meta class is applied to the A
only. How can I solve this? My goal is to preprocess fields of all the children of A
, and I'd like to omit typing metaclass=Meta
in every child.
Upvotes: 1
Views: 186
Reputation: 36329
Since you return type(name, bases, attrs)
you get an object of type type
instead of Meta
. You can check this by printing A.__class__
. Instead you should return:
return super().__new__(cls, name, bases, attrs)
Upvotes: 3
Reputation: 70397
Your metaclass is not actually Meta
. If you do type(a)
, you get <class 'type'>
, because you overrode Meta.__new__
to return an ordinary type
, not a Meta
instance.
Generally speaking, like with ordinary classes, with metaclasses you want to override __init__
and let __new__
do the default thing.
class Meta(type):
def __init__(self, name, supers, attrs):
print(name)
Then you'll see both A
and B
printed, as desired.
Upvotes: 1