• Python多重继承


    钻石继承(菱形继承)问题

    钻石菱形

    class A(object):
        def m(self):
            print("m of A called")
    
    class B(A):
        def m(self):
            print("m of B called")
        
    class C(A):
        def m(self):
            print("m of C called")
    
    class D(B,C):
        pass
    

    钻石问题主要关注如下两个问题(参考文章:python 多重继承的事):

    1. 父类方法的调用顺序上(下面一小节)
    2. 比如若B和C中的m方法也同时调用了A中的m方法时,重复执行的问题
    class A:
        def m(self):
            print("m of A called")
    
    class B(A):
        def m(self):
            print("m of B called")
            A.m(self)
        
    class C(A):
        def m(self):
            print("m of C called")
            A.m(self)
    
    class D(B,C):
        def m(self):
            print("m of D called")
            B.m(self)
            C.m(self)
    

    输出结果:

    m of D called
    m of B called
    m of A called
    m of C called
    m of A called
    

    其实上面两个问题的根源都跟MRO有关,MRO(Method Resolution Order)也叫方法解析顺序,主要用于在多重继承时判断调的属性来自于哪个类,其使用了一种叫做C3的算法,其基本思想时在避免同一类被调用多次的前提下,使用广度优先和从左到右的原则去寻找需要的属性和方法。
    问题二的解决方案如下:

    class A(object):
        def m(self):
            print("m of A called")
    
    class B(A):
        def m(self):
            print("m of B called")
            super().m()
        
    class C(A):
        def m(self):
            print("m of C called")
            super().m()
    
    class D(B,C):
        def m(self):
            print("m of D called")
            super().m()
    

    输出如下:

    m of D called
    m of B called
    m of C called
    m of A called
    

    多继承搜索__init__方法的两种策略

    在当前类中没有init方法,木有覆盖的情况下,多重继承搜索策略(参考:python3 多继承搜索__init__方法的两种策略):

    class A(object): 
        def __init__(self):
            print('A')
     
    class B(object): 
        def __init__(self):
            print('B')
    
    class C(A): 
        def __init__(self):
            print('C') 
     
    class D(B): 
        def __init__(self):
            print('D') 
     
    class E(C, D):
        pass
    

    不同祖先

    这种情形下,python3搜索__init__方法的顺序是 E->C->A->D->B

    不同祖先

    相同祖先

    这种情况下python3搜索__init__方法的顺序是 E->C->D->A

    相同祖先

    在当前的类中,有init方法,在该init的方法中,有super().init()方法(只能调用第一个父类的方法),结论也是类似:

    class A(object): 
        def __init__(self):
            print('A')
     
    class B(object): 
        def __init__(self):
            print('B')
    
    class C(A): 
        def __init__(self):
            print('C') 
     
    class D(B): 
        def __init__(self):
            print('D') 
     
    class E(C, D):
        def __init__(self):
            print('E')
            super().init()    
    

    python 多重继承属性初始化

    键值对初始化

    知识摘抄过来,没有实战经验

    # base classes
    
    class A:
        def __init__(self, a1, a2, **kwargs):
            super().__init__(**kwargs)
            self.a1 = a1
            self.a2 = a2
    
        def funa(self):
            print("I'm funa")
    
    class B:
        def __init__(self, b1, **kwargs):
            super().__init__(**kwargs)
            self.b1 = b1
    
        def funb(self):
            print("I'm funb")
            
    class C:
        def __init__(self, c1, c2, c3, **kwargs):
            super().__init__(**kwargs)
            self.c1 = c1
            self.c2 = c2
            self.c3 = c3
    
        def func(self):
            print("I'm func")
    # derived classes
    
    class X(B, A, C):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
            
    class Y(A, B):
        def __init__(self, **kwargs):
            super().__init__(**kwargs)
    

    调用类名+ init 方法

    class A(object):
        def __init__(self, a1,a2):
            # super(ClassName, self).__init__()
            self.a1 = a1
            self.a2 = a2
    
        def funa(self):
            print("I'm funa")
    
    class B(object):
        def __init__(self, b1):
            # super(ClassName, self).__init__()
            self.b1 = b1
    
        def funb(self):
            print("I'm funb")
            
    class C(A, B):
        def __init__(self, a1, a2, b1):
            A.__init__(self, a1, a2)
            B.__init__(self, b1)
    
    c = C(1, 2, 3)
    dir(c)
    

    参考文章

  • 相关阅读:
    构建之法第十三~十七章阅读
    构建之法第十,十一,十二章阅读
    构建之法第八,九,十章阅读
    Sprint会议计划
    作业6
    作业5 四则运算 测试与封装 5.2
    作业5 四则运算 测试与封装 5.1
    构建之法2
    做汉堡
    构建之法阅读
  • 原文地址:https://www.cnblogs.com/meiguhuaxian/p/13063659.html
Copyright © 2020-2023  润新知