解决python super()调用多重继承函数的问题


Posted in Python onJune 26, 2019

当类间继承关系很简单时,super()的使用很简单。

class A(object):
 def __init__(self):
  print('a')
 
 
class B(A):
 def __init__(self):
  super(B, self).__init__()
  print('b')
 
b = B()

输出结果:

a
b

当一个类继承多个类时,问题就复杂起来了,请看下例:

class A(object):
 def __init__(self):
  print('a')
 
 
class B(object):
 def __init__(self):
  print('b')
  
  
class C(A, B):
 def __init__(self):
  super(C, self).__init__()
  print('c')
 
c = C()

咋一看,情况好像也不复杂,结果输出a, c嘛。没错!但是如果C类想同时调用A与B的__init__()呢?

有童鞋就要说了,我显示调用不就OK了嘛?

class A(object):
 def __init__(self):
  print('a')
 
 
class B(object):
 def __init__(self):
  print('b')
  
  
class C(A, B):
 def __init__(self):
  A.__init__()
  B.__init__()
  print('c')
 
c = C()

效果一样,还不够好。因为没有调用super(),super的一大好处在于,当父类的名字修改时,其继承类不用修改调用方法。

下面给出完美解决方案:

class A(object):
 def __init__(self):
  super(A, self).__init__()
  print('a')
 
 
class B(object):
 def __init__(self):
  super(B, self).__init__()
  print('b')
 
 
class C(A, B):
 def __init__(self):
  super(C, self).__init__()
  print('c')
 
print(C.mro())
c = C()

print(C.mro()),在实际中可以去掉,为啥写在这里,后面再说。

输出结果:

[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]
b
a
c

注意:输出结果是b, a, c 而非a, b, c。为什么?

这里就要用上面的mro()输出来解释了。MRO全称Method Resolution Order, 就是用来定义继承方法的调用顺序,自Python2.3以来,MRO采用广度优先(区别于深度优先)的规则定义。按广度优先的规则,出来的顺序就是:

[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <type 'object'>]

而每次调用super()则是,调用MRO中下一个函数。上面的例子中:super(C, self)则指向MRO中的下一个类(A), 于是调用A的init --> 在A的init中,又调用了super(),于是调用MRO中的下一个函数(B) --> B调用下一个(object), object啥也不干 --> 返回B中,print('b') --> 返回A中,print('a') --> 返回C中,print('c')。

这里再次强调一次,super(type, obj).func()函数调用的是,obj实例在MRO中下一个父类的可调用func(),而不是type的父类中的func()(这个是本文第一个示例给你带来的错觉)。

以上这篇解决python super()调用多重继承函数的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python中执行shell命令的几个方法小结
Sep 18 Python
在Python程序中操作文件之flush()方法的使用教程
May 24 Python
python从入门到精通(DAY 3)
Dec 20 Python
python装饰器初探(推荐)
Jul 21 Python
django Serializer序列化使用方法详解
Oct 16 Python
Python面向对象之继承和多态用法分析
Jun 08 Python
Django 查询数据库并返回页面的例子
Aug 12 Python
Django之form组件自动校验数据实现
Jan 14 Python
django 实现手动存储文件到model的FileField
Mar 30 Python
利用python绘制数据曲线图的实现
Apr 09 Python
python实现web邮箱扫描的示例(附源码)
Mar 30 Python
Python中22个万用公式的小结
Jul 21 Python
Python实现获取系统临时目录及临时文件的方法示例
Jun 26 #Python
python里dict变成list实例方法
Jun 26 #Python
Python音频操作工具PyAudio上手教程详解
Jun 26 #Python
python3中类的继承以及self和super的区别详解
Jun 26 #Python
对Python中class和instance以及self的用法详解
Jun 26 #Python
Python中的支持向量机SVM的使用(附实例代码)
Jun 26 #Python
对python 中class与变量的使用方法详解
Jun 26 #Python
You might like
PHP.MVC的模板标签系统(一)
2006/09/05 PHP
高亮度显示php源代码
2006/10/09 PHP
PHP与MySQL交互使用详解
2006/10/09 PHP
PHP+jquery实时显示网站在线人数的方法
2015/01/04 PHP
浅谈PHP eval()函数定义和用法
2016/06/21 PHP
Yii2――使用数据库操作汇总(增删查改、事务)
2016/12/19 PHP
datePicker——日期选择控件(with jquery)
2007/02/20 Javascript
jQuery学习笔记之jQuery的事件
2010/12/22 Javascript
jQuery实现鼠标经过弹出提示信息的地图热点效果
2015/08/07 Javascript
javascript如何写热点图
2015/12/08 Javascript
jqGrid 学习笔记整理——进阶篇(一 )
2016/04/17 Javascript
jQuery Ajax和getJSON获取后台普通json数据和层级json数据用法分析
2016/06/08 Javascript
微信小程序 教程之数据绑定
2016/10/18 Javascript
Bootstrap CSS组件之导航(nav)
2016/12/17 Javascript
利用transition实现文字上下抖动的效果
2017/01/21 Javascript
angularjs2中父子组件的数据传递的实例代码
2017/07/05 Javascript
Vue实现内部组件轮播切换效果的示例代码
2018/04/07 Javascript
JS如何定义用字符串拼接的变量
2020/07/11 Javascript
浅谈vue单页面中有多个echarts图表时的公用代码写法
2020/07/19 Javascript
使用python在校内发人人网状态(人人网看状态)
2014/02/19 Python
疯狂上涨的Python 开发者应从2.x还是3.x着手?
2017/11/16 Python
python中的set实现不重复的排序原理
2018/01/24 Python
Python 读写文件的操作代码
2018/09/20 Python
Python pyinotify模块实现对文档的实时监控功能方法
2018/10/13 Python
Python二叉树的镜像转换实现方法示例
2019/03/06 Python
Opencv+Python实现图像运动模糊和高斯模糊的示例
2019/04/11 Python
详解FireFox下Canvas使用图像合成绘制SVG的Bug
2019/07/10 HTML / CSS
英国美发和美容产品商城:HQhair
2019/02/08 全球购物
店长岗位的工作内容
2013/11/12 职场文书
建材投资建议书
2014/05/16 职场文书
师范毕业生求职信
2014/07/11 职场文书
员工辞退通知书
2015/04/17 职场文书
公司周年庆典致辞
2015/07/30 职场文书
2016入党积极分子心得体会
2016/01/06 职场文书
python实现批量提取指定文件夹下同类型文件
2021/04/05 Python
Python中Selenium对Cookie的操作方法
2021/07/09 Python