В следующем коде:
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
Я ожидаю, что и A
, и B
будут напечатаны, но я вижу, что метакласс применяется только к A
. Как я могу это решить? Моя цель - предварительно обработать поля всех дочерних элементов A
, и я бы хотел не вводить metaclass=Meta
в каждом дочернем элементе.
Ваш метакласс на самом деле не Meta
. Если вы сделаете type(a)
, вы получите <class 'type'>
, потому что вы переопределили Meta.__new__
, чтобы вернуть обычный экземпляр type
, а не экземпляр Meta
.
Вообще говоря, как и в случае с обычными классами, с метаклассами вы хотите переопределить __init__
и позволить __new__
делать то, что по умолчанию.
class Meta(type):
def __init__(self, name, supers, attrs):
print(name)
Затем вы увидите, что и A
, и B
напечатаны по желанию.
Поскольку вы возвращаете type(name, bases, attrs)
, вы получаете объект типа type
вместо Meta
. Вы можете проверить это, распечатав A.__class__
. Вместо этого вы должны вернуть:
return super().__new__(cls, name, bases, attrs)
АйванФ.: Кроме того, хотя то, что у вас есть, не является неправильным, объявление базового класса можно сократить до простого
class A(metaclass=Meta):
.