使用Python元类A
创建新的类B
。
当C
继承自B
时,为何调用A
的{{1}}方法?
__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
答案 0 :(得分:2)
类是元类的实例,默认元类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
此操作的目的是为define how classes are created存在MetaClass。这包括子类。对每个子类调用__new__
可以使元类对新的类主体,其他基础和名称空间以及关键字做出反应。