解决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在指定目录下查找gif文件的方法
May 04 Python
浅谈Python数据类型判断及列表脚本操作
Nov 04 Python
利用Python脚本实现ping百度和google的方法
Jan 24 Python
Django查询数据库的性能优化示例代码
Sep 24 Python
Python实现破解12306图片验证码的方法分析
Dec 29 Python
python中的json总结
Oct 11 Python
解决pycharm运行出错,代码正确结果不显示的问题
Nov 30 Python
python opencv调用笔记本摄像头
Aug 28 Python
Python高级特性之闭包与装饰器实例详解
Nov 19 Python
python 实现单通道转3通道
Dec 03 Python
pytorch torch.nn.AdaptiveAvgPool2d()自适应平均池化函数详解
Jan 03 Python
python中字典增加和删除使用方法
Sep 30 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 smarty模版引擎中的缓存应用
2009/12/11 PHP
解析PHP中的正则表达式以及模式匹配
2013/06/19 PHP
php生成Android客户端扫描可登录的二维码
2016/05/13 PHP
自制基于jQuery的智能提示插件一枚
2011/02/18 Javascript
将文本输入框内容加入表中的js代码
2013/08/18 Javascript
jquery 判断滚动条到达了底部和顶端的方法
2014/04/02 Javascript
jQuery实现点击查看大图并以弹框的形式居中
2016/08/08 Javascript
Nodejs连接mysql并实现增、删、改、查操作的方法详解
2018/01/04 NodeJs
微信小程序实现全局搜索代码高亮的示例
2018/03/30 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【矩形情况】
2018/12/13 Javascript
JavaScript实现的鼠标跟随特效示例【2则实例】
2018/12/22 Javascript
小程序中手机号识别的示例
2020/12/14 Javascript
Python 初始化多维数组代码
2008/09/06 Python
python中的__slots__使用示例
2015/02/26 Python
分享一个常用的Python模拟登陆类
2015/03/29 Python
Python Matplotlib库入门指南
2015/05/18 Python
Python实现的使用telnet登陆聊天室实例
2015/06/17 Python
利用Python-iGraph如何绘制贴吧/微博的好友关系图详解
2017/11/02 Python
python抓取文件夹的所有文件
2018/02/27 Python
python找出完数的方法
2018/11/12 Python
Python使用python-docx读写word文档
2019/08/26 Python
Python IDLE或shell中切换路径的操作
2020/03/09 Python
python实现提取COCO,VOC数据集中特定的类
2020/03/10 Python
Django多数据库配置及逆向生成model教程
2020/03/28 Python
Python 3.9的到来到底是意味着什么
2020/10/14 Python
CSS3自定义滚动条样式的示例代码
2017/08/21 HTML / CSS
Harrods英国:世界领先的奢侈品百货商店
2020/09/23 全球购物
办公室前台岗位职责
2014/01/04 职场文书
活动总结的格式
2014/05/07 职场文书
小学教育见习报告
2014/10/31 职场文书
幼儿园父亲节活动总结
2015/02/12 职场文书
大学生英文求职信范文
2015/03/19 职场文书
2015年暑期社会实践活动总结
2015/03/27 职场文书
经济纠纷起诉状
2015/05/20 职场文书
2016先进工作者事迹材料
2016/02/25 职场文书
详解Python中*args和**kwargs的使用
2022/04/07 Python