为什么调用元类的 __new__

Why the metaclass' s __new__ is called

使用 Python metaclass A 创建一个新的 class B.

C继承自B时,为什么要调用A__new__方法?

class A(type):
    def __new__(cls, name, bases, attrs):
        print(" call A.__new__  ")
        return type.__new__(cls, name, bases, attrs)


B = A("B", (), {})


class C(B):
    pass                  
python test.py 
call A.__new__  
call A.__new__  

类 是 Metaclasses 的实例,默认的 Metaclass type 来自 object。 Metaclasses 遵循创建实例的常规规则 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

当我们的 class 是元 class 时也会发生同样的情况 - 它仍然是 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

重申一下,如果aA的一个实例,那么A.__new__被用来创建a。这同样适用于 classes 和 metaclasses,因为前者是后者的实例。

A class 不从其元class 继承__new__。一个class一个metaclass,metaclass'__new__用来创建class。


从class(元class的实例)继承时,元class也会被继承。这意味着子class是也是元class的一个实例。因此,元class的__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

这样做的目的是Meta类存在到define how classes are created。这包括 subclasses。为每个 subclass 调用 __new__ 允许 metaclass 对新的 class 主体、额外的基础和名称空间以及关键字做出反应。