zoukankan      html  css  js  c++  java
  • python基础——继承实现的原理

    python基础——继承实现的原理

    1 继承顺序

    class A(object):
        def test(self):
            print('from A')
    
    class B(A):
        def test(self):
            print('from B')
    
    class C(A):
        def test(self):
            print('from C')
    
    class D(B):
        def test(self):
            print('from D')
    
    class E(C):
        def test(self):
            print('from E')
    
    class F(D,E):
        # def test(self):
        #     print('from F')
        pass
    f1=F()
    f1.test()
    print(F.__mro__) #只有新式才有这个属性可以查看线性列表,经典类没有这个属性
    
    #新式类继承顺序:F->D->B->E->C->A
    #经典类继承顺序:F->D->B->A->E->C
    #python3中统一都是新式类
    #pyhon2中才分新式类与经典类
    

      

    2 继承原理(python如何实现的继承)

    python到底是如何实现继承的,对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表,例如

    >>> F.mro() #等同于F.__mro__
    [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>,
    <class 'object'>]

     为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止 

    合并所有父类的MRO列表并遵循如下三条准则:
    1.子类会先于父类被检查
    2.多个父类会根据它们在列表中的顺序被检查
    3.如果对下一个类存在两个合法的选择,选择第一个父类

    3 子类中调用父类方法(super()方法)

    子类继承了父类的方法,然后想进行修改,注意了是基于原有的基础上修改,那么就需要在子类中调用父类的方法

    方法一  父类名.父类方法()

    class People:
        def __init__(self,name,sex,age):
            self.name=name
            self.sex=sex
            self.age=age
        def walk(self):
         print('%s is walking'%self.name)
    
    class Chinese(People):
        country='China'
        def __init__(self,name,sex,age,language='Chinses'):
            People.__init__(self,name,sex,age)
            self.language=language
        def walk(self,x):
            pass
    
    c=Chinese('xiaojing','male',20)
    print(c.name,c.sex,c.age,c.language)

    方法二 super()方法

    class People:
        def __init__(self,name,sex,age):
            self.name=name
            self.age=age
            self.sex=sex
        def walk(self):
            print('%s is walking'%self.name)
    class Chinese(People):
        country='China'
        def __init__(self,name,sex,age,language='Chinese'):
            super().__init__(name,sex,age)  #super() 绑定 调用父类方法
            self.language=language
        def walk(self,x):
            super().walk()
            print("---->子类的x",x)
    c=Chinese('EGG','male','20')
    c.walk(123)
    

    不用super引发的惨案 

    #每个类中都继承了且重写了父类的方法
    class A:
        def __init__(self):
            print('A的构造方法')
    class B(A):
        def __init__(self):
            print('B的构造方法')
            A.__init__(self)
    
    
    class C(A):
        def __init__(self):
            print('C的构造方法')
            A.__init__(self)
    
    
    class D(B,C):
        def __init__(self):
            print('D的构造方法')
            B.__init__(self)
            C.__init__(self)
    
        pass
    f1=D()
    
    print(D.__mro__) #python2中没有这个属性

    当你使用super()函数时,Python会在MRO列表上继续搜索下一个类。只要每个重定义的方法统一使用super()并只调用它一次,那么控制流最终会遍历完整个MRO列表,每个方法也只会被调用一次(注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表

    #每个类中都继承了且重写了父类的方法
    class A:
        def __init__(self):
            print('A的构造方法')
    class B(A):
        def __init__(self):
            print('B的构造方法')
            super(B,self).__init__()
    
    
    class C(A):
        def __init__(self):
            print('C的构造方法')
            super(C,self).__init__()
    
    
    class D(B,C):
        def __init__(self):
            print('D的构造方法')
            super(D,self).__init__()
    
    f1=D()
    
    print(D.__mro__) #python2中没有这个属性
    
  • 相关阅读:
    从小知识开始练习
    shell的基本语法
    shell的一些简单用法
    HTML 父元素与子元素之间的margin-top问题
    HTML input文本框设置和移除默认值
    c# winform进入窗口后在文本框里的默认焦点
    c#面向对象基础 重写、虚方法、抽象类
    c#面向对象基础 封装、继承
    c#面向对象基础 静态成员、构造函数、命名空间与类库
    c#面向对象基础 类、方法、方法重载
  • 原文地址:https://www.cnblogs.com/niejinmei/p/6768223.html
Copyright © 2011-2022 走看看