В файле с именем exp.py (ниже) я пытаюсь понять метаклассы в Python. Похоже, что когда метод __new__
метакласса использует конструктор 'type' для создания класса, его метод __new__
не вызывается подклассом класса, использующего его в качестве метакласса:
class A(type):
def __new__(cls, name, bases, dct):
print "cls is: ", cls
print "name is: ", name
print "bases is: ", bases
print "dct is: ", dct
print
return super(A, cls).__new__(cls, name, bases, dct)
class B(object):
__metaclass__ = A
class C(B): pass
class D(type):
def __new__(cls, name, bases, dct):
print "cls is: ", cls
print "name is: ", name
print "bases is: ", bases
print "dct is: ", dct
return type(name, bases, dct)
class E(object):
__metaclass__ = D
class F(E): pass
В терминале:
>>> from exp import *
cls is: <class 'exp.A'>
name is: B
bases is: (<type 'object'>,)
dct is: {'count': 0, '__module__': 'exp', '__metaclass__': <class 'exp.A'>, '__init__': <function __init__ at 0x107eb9578>}
cls is: <class 'exp.A'>
name is: C
bases is: (<class 'exp.B'>,)
dct is: {'__module__': 'exp'}
cls is: <class 'exp.D'>
name is: E
bases is: (<type 'object'>,)
dct is: {'count': 0, '__module__': 'exp', '__metaclass__': <class 'exp.D'>, '__init__': <function __init__ at 0x107ebdb18>}
>>>
Как видите, метод __new__
метакласса D не вызывается при загрузке определения класса F. (Если бы он был вызван, то была бы напечатана и информация о классе F.)
Может ли кто-нибудь помочь мне объяснить это?
Сообщение по теме: я читал Что такое метакласс в Python? и, кажется, встречает что-то похожее в предложении: «Будьте осторожны, здесь атрибут __metaclass__
не будет унаследован, метакласс родителя (Bar.__class__
) будет унаследован. Если Bar использовал атрибут __metaclass__
, который создал Bar с type()
(а не type.__new__()
), подклассы не будут наследовать это поведение». Но я не понял этого до конца.