Metaclass не вызывается в подклассах
вот сеанс python.
>>> class Z(type):
def __new__(cls, name, bases, attrs):
print cls
print name
return type(name, bases, attrs)
...
>>> class Y(object):
__metaclass__ = Z
...
<class '__main__.Z'>
Y
>>> class X(Y):
... pass
...
>>> class W(Y):
... __metaclass__ = Z
...
<class '__main__.Z'>
W
>>>
после определения класса X я ожидаю, что Z._new__ будет вызван для него и напечатает две строки, чего не происходит (как метакласс наследуются?)
1 ответов
проблема в том, что cls
аргумент (который является объектом metaclass) не передается при вызове type
, поэтому объект класса Y
то, что создано и возвращено, не имеет никакой ссылки на metaclass Z
.
если вы замените последнюю строку __new__
С
return super(Z, cls).__new__(cls, name, bases, attrs)
тогда это работает. Обратите внимание, что хотя cls
используется super
мы все еще должны обеспечить cls
в качестве аргумента, поскольку super
здесь возвращает несвязанный метод (см. здесь для более).
в качестве альтернативы использованию super можно использовать:
return type.__new__(cls, name, bases, attrs)
важно то, что мы даем cls
(наш объект метакласса Z
) в classmethod __new__
. Более короткая форма type(name, bases, attrs)
заполняет на cls
аргумент, который, конечно, неверен. Эта ошибка похожа на вызов метода экземпляра с неправильным