我不明白为什么结果是“ B的__new __()调用A的__init __()调用A的__new __()调用”

时间:2019-12-21 01:51:30

标签: python oop

class A:
    def __new__(self):
        self.__init__(self)
        print("A's __new__() invoked") #print if called

    def __init__(self):
        print("A's __init__() invoked") #print if called

class B(A):
    def __new__(self):
        print("B's __new__() invoked") #print if called

    def __init__(self):
        print("B's __init__() invoked") #print if called

def main():
    b = B() #create an object of B
    a = A() #create an object of A

main() 

为什么结果是“ B的 new ()调用A的 init ()调用A的 new ()调用?我想知道为什么B的<不会调用strong> init 方法。

1 个答案:

答案 0 :(得分:1)

对于类Foo,只有Foo.__init__返回Foo()的实例时,Foo.__new__才会由Foo自动调用。 B.__new__返回None,因此不会调用B.__init__

A.__init__之所以被调用,是因为A.__new__已显式调用了它,尽管它不是有意义的方式,因为它是由类A本身而不是{{1}的实例传递的}。

A调用Foo(),您可以想象该方法的定义有点像

type(Foo).__call__(Foo)

如果您定义def __call__(cls, *args, **kwargs): obj = cls.__new__(cls, *args, **kwargs) if isinstance(obj, cls): cls.__init__(obj) return obj ,请注意以下几点:

  1. __new__是一个静态方法(尽管Python对此进行了特殊处理,因此您不需要__new__装饰)会首先接收 class 参数,因此参数的名称应反映出来。

  2. 在大多数情况下,@staticmethod的目的是调用__new__以获取该类的实例,可能会做一些 在返回新对象之前对其进行后处理。

  3. 由于super().__new__将在新实例上被自动调用(假设它的类型正确),因此__init__不应调用__new__本身。

    < / li>