相关代码 1:
class A(object):
    def show(self):
        print ('init A...')
class B(A):
    def show(self):
        super(B, self).show()
        print('init B...')
class C(A):
    def show(self):
        # super(C, self).show()
        print('init C...')
class D(B, C):
    def show(self):
        super(D, self).show()
        print('init D...')
d = D()
d.show()
输出的结果是:
init C...
init B...
init D...
这里想问的是为什么没有经过 A,输出 init A...
相关代码 2:
class A(object):
    def show(self):
        print ('init A...')
class B(A):
    def show(self):
        super(B, self).show()
        print('init B...')
class C(A):
    def show(self):
        # super(C, self).show()
        print('init C...')
class D(C, B):    #继承类和代码 1 中的顺序相反
    def show(self):
        super(D, self).show()
        print('init D...')
d = D()
d.show()
输出的结果是:
init C...
init D...
这里想问的是为什么 B 中的方法没有被调用? 还有的就是新式类的 MRO 算法采用广度优先搜索。在这里是怎么调用的?
谢谢各位大佬
     1 
                    
                    Outliver0      2018-11-13 09:40:16 +08:00 
                    
                    你可以打印一下__mro__查看顺序 
                 | 
            
     2 
                    
                    coroutine      2018-11-13 09:51:09 +08:00 
                    
                    对于, “为什么没有经过 A,输出 init A... ” 你可以参考 Python Cookbook,第 8 章关于 super 的描述。  类 B 里 show 的 super,实际上调用的是类 C 的 show。  而类 C 的 super 已经被你注释掉了。 
                 | 
            
     3 
                    
                    Outliver0      2018-11-13 09:52:13 +08:00    第一次的 mro 顺序为 
                [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>], super(D, self).show()----> super(B, self).show()------>C.show() C 已经有 show()方法,所有打印顺序为 init C...,init B...,init D... 第二次的 mro 顺序为 [<class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>], super(D, self).show() ----->C.show() C 已经有 show()方法,所有打印顺序为 init C... ,init D...  | 
            
     4 
                    
                    coroutine      2018-11-13 09:58:48 +08:00    super 的调用顺序实际上,与最终该类的 MRO 的顺序有关。你可以从 D.__mro__ 打印出类 D 的类继承顺序。 
                比如您给出的两个例子,的 MRO 分别为 (__main__.D, __main__.B, __main__.C, __main__.A, object); (__main__.D, __main__.C, __main__.B, __main__.A, object) 如何生成 MRO 顺序,就是 cookbook 里提到的 https://en.wikipedia.org/wiki/C3_linearization 了。  | 
            
     5 
                    
                    coroutine      2018-11-13 10:01:31 +08:00 
                    
                    您可以参阅    Python Cookbook Chapter 8:   8.7: Calling a Method on a Parent Class 这一小节。 
                 | 
            
     6 
                    
                    liukeai7777      2018-11-13 10:11:52 +08:00    D 的 mro 是 (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) 
                init C... init B... init D... 所以 super 方法的查找顺序就 DBCA 多以第一个例子 第一步运行到 class D 的 show 方法 , class D show 第一句: [super(D, self).show() 查找 B 的 show 方法。运行到 class B 的 show 方法,classB show 执行第一句:super(B, self).show() 然后又找到 class C 的 show 方法 于是打印第一句 init C,执行第二句 init C ] class D 的 show 第二句 打印 init C 同理第二个例子 MRO 是 DCBA  | 
            
     7 
                    
                    king1101   OP 多谢各位大佬,我已经理解了,其实走入了一个误区,认为 super 就是调用父类的方法,其实 super 指的是 MRO 的下一个类,和父类没有实质关联。 
                 | 
            
     8 
                    
                    zxcvsh      2018-11-13 10:13:14 +08:00 via iPhone    百度一下,拓扑排序,好像是这个关键字;图解说明继承检索的顺序很明了 
                 | 
            
     9 
                    
                    liukeai7777      2018-11-13 10:13:21 +08:00 
                    
                    D 的 mro 是 (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>) 
                init C... init B... init D... 所以 super 方法的查找顺序就 DBCA 多以第一个例子 第一步运行到 class D 的 show 方法 , class D show 第一句: [super(D, self).show() 查找 B 的 show 方法。运行到 class B 的 show 方法,classB show 执行第一句:super(B, self).show() 然后又找到 class C 的 show 方法 于是打印第一句 init C,执行第二句 init B] class D 的 show 第二句 打印 init D 同理第二个例子 MRO 是 DCBA  | 
            
     10 
                    
                    seven777      2018-11-13 14:57:56 +08:00 
                    
                    给楼主一个解药: 
                (我不是程序员,但我觉得如此...) 无论当前的任何编程语言,原理基本想通; 虽然不同语言有不同的“继承”处理方式,但原理相同。 统一标准是: 1,没有什么需求非得复杂的继承来实现,如果有,你设计错了; 2,如果一个继承关系你搞不明白,不是你技术问题,是设计错了,换思路吧; 3,“事不过三”在编程中应该是重要思想,比如继承层级不要超过三层,继承源头不要超过三个,再比如 if,while,等判断关系嵌套不要超过三层... 我瞎说的,但觉得应该如此  | 
            
     11 
                    
                    ticotico      2018-11-13 15:57:49 +08:00 via Android 
                    
                    不是把 C 中 super 注释掉了么,D 中的 super 是按 mro 查找 MRO 中下一位的,MRO 在新式类中按的是 bfs 来拍得,最近刚接触 mro 不知道说得对不对,各位大佬轻拍 
                 | 
            
     12 
                    
                    RomanCavalry      2018-11-15 15:00:16 +08:00 
                    
                    这个就需要了解 Python MRO 的历史了,参考: http://python.jobbole.com/85685/ 
                 |