Классы являются экземплярами метаклассов, а метакласс по умолчанию type
является производным от object
. Таким образом, метаклассы следуют обычным правилам создания экземпляров object
- __new__
конструирует экземпляр, __init__
может инициализировать его.
>>> class DemoClass(object):
... def __new__(cls):
... print('__new__ object of DemoClass')
... return super().__new__(cls)
...
... def __init__(self):
... print('__init__ object of DemoClass')
... return super().__init__()
...
>>> demo_instance = DemoClass() # instantiate DemoClass
__new__ object of DemoClass
__init__ object of DemoClass
То же самое происходит, когда наш класс является метаклассом - он все еще является object
и ведет себя как таковой.
>>> class DemoType(type):
... def __new__(mcs, name, bases, attrs):
... print('__new__ object %r of DemoType' % name)
... return super().__new__(mcs, name, bases, attrs)
...
... def __init__(self, name, bases, attrs):
... print('__init__ object %r of DemoType' % name)
... return super().__init__(name, bases, attrs)
...
>>> demo_class = DemoType('demo_class', (), {}) # instantiate DemoType
__new__ object 'demo_class' of DemoType
__init__ object 'demo_class' of DemoType
Повторюсь, если a
является экземпляром A
, то A.__new__
использовался для создания a
. То же самое относится к классам и метаклассам, поскольку первые являются экземплярами последних.
Класс не наследует __new__
от своего метакласса. Класс имеет метакласс, а метакласс '__new__
используется для создания класса.
При наследовании от класса (экземпляра метакласса) метакласс наследуется также. Это означает, что подкласс также является экземпляром метакласса. Соответственно, и __new__
, и __init__
метакласса используются для создания и инициализации этого экземпляра.
>>> class DemoClass(metaclass=DemoType):
... ...
...
>>> class DemoSubClass(DemoClass):
... ...
...
__new__ object 'DemoClass' of DemoType
__init__ object 'DemoClass' of DemoType
__new__ object 'DemoSubClass' of DemoType
__init__ object 'DemoSubClass' of DemoType
>>> type(DemoClass) # classes are instances of their metaclass
__main__.DemoType
>>> type(DemoSubClass) # subclasses inherit metaclasses from base classes
__main__.DemoType
Цель этого состоит в том, что существуют метаклассы, которые определяют, как создаются классы . Это включает в себя подклассы. Вызов __new__
для каждого подкласса позволяет метаклассу реагировать на тело нового класса, дополнительные базы, пространство имен и ключевые слова.