Python多重继承之菱形继承的实例详解


Posted in Python onFebruary 12, 2020

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

语法

class SubclassName(BaseClass1, BaseClass2, BaseClass3, ...): pass

菱形继承

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

其中,就会出现菱形继承。如下图所示。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实现根据指定端口探测服务器/模块部署的方法
Aug 25 Python
Python多线程编程(四):使用Lock互斥锁
Apr 05 Python
在Python中用keys()方法返回字典键的教程
May 21 Python
神经网络理论基础及Python实现详解
Dec 15 Python
tensorflow中next_batch的具体使用
Feb 02 Python
python将txt文档每行内容循环插入数据库的方法
Dec 28 Python
Python 调用PIL库失败的解决方法
Jan 08 Python
Python爬虫beautifulsoup4常用的解析方法总结
Feb 25 Python
Python通过Manager方式实现多个无关联进程共享数据的实现
Nov 07 Python
详解Python3.8+PyQt5+pyqt5-tools+Pycharm配置详细教程
Nov 02 Python
python中把元组转换为namedtuple方法
Dec 09 Python
Matplotlib中rcParams使用方法
Jan 05 Python
Python实现桌面翻译工具【新手必学】
Feb 12 #Python
PyCharm无法引用自身项目解决方式
Feb 12 #Python
pycharm不能运行.py文件的解决方法
Feb 12 #Python
Python3+Selenium+Chrome实现自动填写WPS表单
Feb 12 #Python
pytorch中使用cuda扩展的实现示例
Feb 12 #Python
pycharm内无法import已安装的模块问题解决
Feb 12 #Python
PyTorch笔记之scatter()函数的使用
Feb 12 #Python
You might like
PHP 中英文混合排版中处理字符串常用的函数
2007/04/12 PHP
php连接mssql数据库的几种方法
2013/02/21 PHP
php封装好的人民币数值转中文大写类
2015/12/20 PHP
微信企业转账之入口类分装php代码
2018/10/01 PHP
Laravel框架实现的上传图片到七牛功能详解
2019/09/06 PHP
Nginx+php配置文件及原理解析
2020/12/09 PHP
Javascript中的delete操作符详细介绍
2014/06/06 Javascript
js操作模态窗口及父子窗口间相互传值示例
2014/06/09 Javascript
一些实用性较高的js方法
2016/04/19 Javascript
使用jquery提交form表单并自定义action的实现代码
2016/05/25 Javascript
jquery实现上传文件大小类型的验证例子(推荐)
2016/06/25 Javascript
EasyUI的TreeGrid的过滤功能的解决思路
2017/08/08 Javascript
AngularJs 终极购物车(实例讲解)
2017/11/08 Javascript
vue-router2.0 组件之间传参及获取动态参数的方法
2017/11/10 Javascript
微信小程序实现无限滚动列表
2020/05/29 Javascript
JavaScript实现单英文金山打字通
2020/07/24 Javascript
[02:41]《西雅图我们来了》2015国际邀请赛出征全记录
2015/07/23 DOTA
[56:20]LGD vs VP Supermajor 败者组决赛 BO3 第三场 6.10
2018/07/04 DOTA
推荐下python/ironpython:从入门到精通
2007/10/02 Python
python实现自动更换ip的方法
2015/05/05 Python
Python中的推导式使用详解
2015/06/03 Python
Python栈类实例分析
2015/06/15 Python
Python时间的精准正则匹配方法分析
2017/08/17 Python
用Python实现读写锁的示例代码
2018/11/05 Python
详解如何用django实现redirect的几种方法总结
2018/11/22 Python
对python数据切割归并算法的实例讲解
2018/12/12 Python
Python新手如何理解循环加载模块
2020/05/29 Python
python温度转换华氏温度实现代码
2020/12/06 Python
python集合的新增元素方法整理
2020/12/07 Python
Python爬虫+tkinter界面实现历史天气查询的思路详解
2021/02/22 Python
中国第一家杂志折扣订阅网:杂志铺
2016/08/30 全球购物
扬尘污染防治方案
2014/06/15 职场文书
放弃遗产继承公证书
2015/01/26 职场文书
应届毕业生的自我评价
2019/06/21 职场文书
Django如何与Ajax交互
2021/04/29 Python
MongoDB数据库部署环境准备及使用介绍
2022/03/21 MongoDB