zoukankan      html  css  js  c++  java
  • 继承的实现原理

    
    

    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列表的构造是通过一个C3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的MRO列表并遵循如下三条准则:

    
    
    1. 子类会先于父类被检查
    2. 多个父类会根据它们在列表中的顺序被检查
    3. 如果对下一个类存在两个合法的选择,选择第一个父类
    
    

    在Java和C#中子类只能继承一个父类,而Python中子类可以同时继承多个父类,如果继承了多个父类,那么属性的查找方式有两种,分别是:深度优先和广度优先


    #在python2中有新式类和经典类之说
    #经典类:

    class Foo:
    pass
    class Bar(Foo):
    pass
    #新式类:

    class Foo1(object):
    pass
    class Bar1(Foo1):
    pass
    #在python3中只有新式类:
    class Foo2:
    pass
    class Bar2(Foo2):
    pass
    print(Bar2.__bases__) #__bases__是查找当前的类继承了几个父类
    print(Foo2.__bases__)



    class A(object):
    def tset(self):
    print('from is A')
    class B(A):
    def test(self):
    print('from is B')
    class C(A):
    def test(self):
    print('from is C')
    class D(B):
    def test(self):
    print('from is E')
    class E(C):
    def tset(self):
    print('from is E')
    class F(D, E):
    def test(self):
    print('from is F')
    print(F.mro()) #mro()是以列表的形式显示出它的对象所调用属性的查找顺序 注意 mro方法只在python3中有效果
    f = F()
    f.test()
    #它们的继承顺序是F, D,B,E,C,A
     
  • 相关阅读:
    对var和let作用域用闭包的特性做最好的解释
    Js函数作用域
    问题记录
    Git学习
    React-router BrowserRouter导致axios请求时会重复url中的某些字段
    leetcode python 032 识别最长合法括号
    leetcode python 030 Substring with Concatenation of All Words
    n阶楼梯,一次走1,2,3步,求多少种不同走法
    leetcode python 012 hard 合并k个有序链表
    leetcode python 011
  • 原文地址:https://www.cnblogs.com/yuexijun/p/10235981.html
Copyright © 2011-2022 走看看