#python #django #oop #inheritance #metaclass
#python #django #ооп #наследование #метакласс
Вопрос:
У меня есть следующий пример кода для Python 2.7:
class MetaA(type):
def __new__(cls, name, bases, attrs):
print('MetaA::__new__')
print('CLS:' str(cls))
print('Name:' name)
print('============================')
return super(MetaA, cls).__new__(cls, name, bases, attrs)
class A(object):
__metaclass__ = MetaA
class MetaB(type(A)):
pass
class SomeMixin(A):
pass
class B(A):
__metaclass__ = MetaB
class C(SomeMixin, B):
pass
После его выполнения у меня есть такой вывод:
MetaA::__new__
CLS:<class '__main__.MetaA'>
Name:A
============================
MetaA::__new__
CLS:<class '__main__.MetaA'>
Name:SomeMixin
============================
MetaA::__new__
CLS:<class '__main__.MetaB'>
Name:B
============================
MetaA::__new__
CLS:<class '__main__.MetaA'>
Name:C
============================
MetaA::__new__
CLS:<class '__main__.MetaB'>
Name:C
============================
Дело в том, что при class C
определении сначала вызывается метод __new__
для метакласса MetaA
(базового), а затем для метакласса MetaB
вызывается.
Если я изменю порядок смешивания и унаследую класс в своем классе C следующим образом
class C(B, SomeMixin):
результат следующий:
MetaA::__new__
CLS:<class '__main__.MetaA'>
Name:A
============================
MetaA::__new__
CLS:<class '__main__.MetaA'>
Name:SomeMixin
============================
MetaA::__new__
CLS:<class '__main__.MetaB'>
Name:B
============================
MetaA::__new__
CLS:<class '__main__.MetaB'>
Name:C
============================
Метод __new__
для метакласса MetaA
в этом случае не вызывается, только для метакласса MetaB
.
Если я выполню почти тот же код в Python 3, несмотря на порядок наследования в class C
, метод __new__
будет вызван только для метакласса MetaA
.
Не мог бы кто-нибудь объяснить, почему это происходит и что было изменено в Python 3 с точки зрения такого поведения?
Спасибо!