zoukankan      html  css  js  c++  java
  • 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)
    

    参考文章

  • 相关阅读:
    Windows 之 手机访问 PC 端本地部署的站点
    Java 之 Given final block not properly padded
    关于ie7下display:inline-block;不支持的解决方案
    Oracle 之 获取当前日期及日期格式化
    WebService 之 实例学习一
    第 3 章 共享程序集和强命名程序集
    第 2 章 生成、打包、部署和管理应用程序及类型
    第一章 CLR的执行模型
    CLR 之 内容概述
    网站跨站点脚本,Sql注入等攻击的处理
  • 原文地址:https://www.cnblogs.com/meiguhuaxian/p/13063659.html
Copyright © 2011-2022 走看看