当前位置: 移动技术网 > IT编程>脚本编程>Python > 菱形继承问题

菱形继承问题

2019年06月08日  | 移动技术网IT编程  | 我要评论

刘雅婷不雅照,死亡绽放 伊莉丝,警犬站姿妖娆成网红

类的分类

新式类

  • 继承了object的类以及该类的子类,都是新式类

  • python3中所有的类都是新式类

经典类

  • 没有继承object的类以及该类的子类,都是经典类

  • 只有python2中才有经典类

菱形继承问题

92-菱形继承问题-继承关机.jpg

在java和c#中子类只能继承一个父类,而python中子类可以同时继承多个父类,如a(b,c,d)

如果继承关系为非菱形结构,则会按照先找b这一条分支,然后再找c这一条分支,最后找d这一条分支的顺序直到找到我们想要的属性

如果继承关系为菱形结构,即子类的父类最后继承了同一个类,那么属性的查找方式有两种:

  • 经典类下:深度优先
  • 广度优先:广度优先

  • 经典类:一条路走到黑,深度优先

92-菱形继承问题-经典类.png

  • 新式类:不找多各类最后继承的同一个类,直接去找下一个父类,广度优先

92-菱形继承问题-新式类.png

class g(object):
    # def test(self):
    #     print('from g')
    pass


print(g.__bases__)


class e(g):
    # def test(self):
    #     print('from e')
    pass


class b(e):
    # def test(self):
    #     print('from b')
    pass


class f(g):
    # def test(self):
    #     print('from f')
    pass


class c(f):
    # def test(self):
    #     print('from c')
    pass


class d(g):
    # def test(self):
    #     print('from d')
    pass


class a(b, c, d):
    def test(self):
        print('from a')


obj = a()
(<class 'object'>,)
obj.test()  # a->b->e-c-f-d->g-object
from a

c3算法与mro()方法介绍

92-菱形继承问题-飞船原理.jpg

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

print(a.mro())  # a.__mro__
[<class '__main__.a'>, <class '__main__.b'>, <class '__main__.e'>, <class '__main__.c'>, <class '__main__.f'>, <class '__main__.d'>, <class '__main__.g'>, <class 'object'>]
for i in a.mro():
    print(i)
<class '__main__.a'>
<class '__main__.b'>
<class '__main__.e'>
<class '__main__.c'>
<class '__main__.f'>
<class '__main__.d'>
<class '__main__.g'>
<class 'object'>

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

而这个mro列表的构造是通过一个c3线性化算法来实现的。我们不去深究这个算法的数学原理,它实际上就是合并所有父类的mro列表并遵循如下三条准则:

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网