代码之家  ›  专栏  ›  技术社区  ›  user541686

为什么在执行Base时跳过了一个uuu init uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?

  •  10
  • user541686  · 技术社区  · 7 年前

    为什么? 确切地

    A.__init__()
    B.__init__()
    D.__init__()
    

    按以下代码打印?特别地:

    1. C.__init__() 印刷的?

    2. 为什么是 C.\uuu初始化() 如果我把 super().__init__() A.__init__(self) ?

    #!/usr/bin/env python3
    
    class A(object):
        def __init__(self):
            super(A, self).__init__()
            print("A.__init__()")
    class B(A):
        def __init__(self):
            A.__init__(self)
            print("B.__init__()")
    class C(A):
        def __init__(self):
            A.__init__(self)
            print("C.__init__()")
    class D(B, C):
        def __init__(self):
            super(D, self).__init__()
            print("D.__init__()")
    
    D()
    
    1 回复  |  直到 7 年前
        1
  •  6
  •   user541686    7 年前

    热释光;医生:因为 B.__init__ C.__init__ 通过 super(B, self).__init__() ,而你绕过了那个电话。


    因为你没告诉我。多重继承涉及协作,并且您使用了显式类引用,否认了这种协作。

    你把所有“超级喜欢”的电话都换成了 super().__init__() (因为您已经将其标记为Python 3)您将看到如下输出:

    A.__init__()
    C.__init__()
    B.__init__()
    D.__init__()
    

    事实上,如果你只是改变一下,你就会看到这个输出 B 的“超级喜欢”呼叫:

    super(B, self).__init__()
    super().__init__()
    

    那么为什么A在你的情况下不叫C呢?

    如果我把super()。\uu init\uuuuuuuuuuuuuuuuuuuuu()而不是一个.。\uu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?

    因为 the no-argument super() goes left to right ,所以 B 首先查看,然后在B内部使用显式类引用( A.__init__(self) ). 在这样做的过程中,你失去了所有的(大多数)上下文 C .

    super() 是什么帮助你导航MRO,并让你 C.__init__() 是你让的。但是在 你只是在调用 A .

    C.\uuu初始化() C 仍然出现在 D.__bases__

    (<class '__main__.B'>, <class '__main__.C'>)
    

    在里面 D.__mro__ :

    (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
    

    isinstance(D(), C) is True .

    简而言之,Python C 是的超类 D ,但你给了 C.。\u初始__ 结束你的跑步 B.。\初始化__ 实施。