登录  /  注册

Python多重继承中的菱形继承

angryTom
发布: 2020-02-12 12:45:03
转载
3896人浏览过

本篇文章介绍了python多重继承中,菱形继承的的用法,希望对学习python中的朋友有帮助!

Python多重继承中的菱形继承

继承是面向对象编程的一个重要的方式,通过继承,子类就可以扩展父类的功能。在python中一个类能继承自不止一个父类,这叫做python的多重继承(Multiple Inheritance )。

语法

class SubclassName(BaseClass1, BaseClass2, BaseClass3, ...):
    pass
登录后复制

菱形继承

推荐学习:Python视频教程

在多层继承和多继承同时使用的情况下,就会出现复杂的继承关系,多重多继承。

其中,就会出现菱形继承。如下图所示。mark

在这种结构中,在调用顺序上就出现了疑惑,调用顺序究竟是以下哪一种顺序呢

  • D->B->A->C(深度优先)
  • D->B->C->A(广度优先)

下面我们来解答下这个问题。

举个例子来看下:

class A():
    def __init__(self):
        print('init A...')
        print('end A...')

class B(A):
    def __init__(self):
        print('init B...')
        A.__init__(self)
        print('end B...')

class C(A):
    def __init__(self):
        print('init C...')
        A.__init__(self)
        print('end C...')

class D(B, C):
    def __init__(self):
        print('init D...')
        B.__init__(self)
        C.__init__(self)
        print('end D...')

if __name__ == '__main__':
    D()
登录后复制

输出结果

init D...
init B...
init A...
end A...
end B...
init C...
init A...
end A...
end C...
end D...
登录后复制

从输出结果中看,调用顺序为:D->B->A->C->A。可以看到,B、C共同继承于A,A被调用了两次。A没必要重复调用两次。

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

那么如何避免顶层父类中的某个方法被多次调用呢,此时就需要super()来发挥作用了,super本质上是一个类,内部记录着MRO信息,由于C3算法确保同一个类只会被搜寻一次,这样就避免了顶层父类中的方法被多次执行了,上面代码可以改为:

class A():
    def __init__(self):
        print('init A...')
        print('end A...')

class B(A):
    def __init__(self):
        print('init B...')
        super(B, self).__init__()
        print('end B...')

class C(A):
    def __init__(self):
        print('init C...')
        super(C, self).__init__()
        print('end C...')

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

if __name__ == '__main__':
    D()
登录后复制

输出结果:

init D...
init B...
init C...
init A...
end A...
end C...
end B...
end D...
登录后复制

可以看出,此时的调用顺序是D->B->C->A。即采用是广度优先的遍历方式。

补充内容

Python类分为两种,一种叫经典类,一种叫新式类。都支持多继承,但继承顺序不同。

  • 新式类:从object继承来的类。(如:class A(object)),采用广度优先搜索的方式继承(即先水平搜索,再向上搜索)。
  • 经典类:不从object继承来的类。(如:class A()),采用深度优先搜索的方式继承(即先深入继承树的左侧,再返回,再找右侧)。

Python2.x中类的是有经典类和新式类两种。Python3.x中都是新式类。

更多python相关教程,请关注python教程栏目。

以上就是Python多重继承中的菱形继承的详细内容,更多请关注php中文网其它相关文章!

智能AI问答
PHP中文网智能助手能迅速回答你的编程问题,提供实时的代码和解决方案,帮助你解决各种难题。不仅如此,它还能提供编程资源和学习指导,帮助你快速提升编程技能。无论你是初学者还是专业人士,AI智能助手都能成为你的可靠助手,助力你在编程领域取得更大的成就。
来源:博客园网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
最新问题
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号