解决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 相关文章推荐
python3.0 字典key排序
Dec 24 Python
讲解Python中for循环下的索引变量的作用域
Apr 15 Python
Pyhton中单行和多行注释的使用方法及规范
Oct 11 Python
python中单例常用的几种实现方法总结
Oct 13 Python
Django 路由控制的实现代码
Nov 08 Python
python url 参数修改方法
Dec 26 Python
python使用mitmproxy抓取浏览器请求的方法
Jul 02 Python
Python imread、newaxis用法详解
Nov 04 Python
pycharm中import呈现灰色原因的解决方法
Mar 04 Python
哪些是python中web开发框架
Jun 17 Python
python简单实现插入排序实例代码
Dec 16 Python
python 实现一个简单的线性回归案例
Dec 17 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新闻发布系统教程
2014/05/09 PHP
PHP+swoole实现简单多人在线聊天群发
2016/01/19 PHP
js常用函数 不错
2006/09/08 Javascript
Javascript实例教程(19) 使用HoTMetal(7)
2006/12/23 Javascript
JavaScript 继承详解 第一篇
2009/08/30 Javascript
js实现通用的微信分享组件示例
2014/03/10 Javascript
JQuery显示、隐藏div的几种方法简明总结
2015/04/16 Javascript
JavaScript实现的背景自动变色代码
2015/10/17 Javascript
jQuery移动页面开发中的触摸事件与虚拟鼠标事件简介
2015/12/03 Javascript
Javascript 字符串模板的简单实现
2016/02/13 Javascript
JS模拟bootstrap下拉菜单效果实例
2016/06/17 Javascript
原生javascript 学习之js变量全面了解
2016/07/14 Javascript
Bootstrap被封装的弹层
2016/07/20 Javascript
详谈js中数组(array)和对象(object)的区别
2017/02/27 Javascript
Angular2 组件通信的实例代码
2017/06/23 Javascript
基于Vue实现拖拽功能
2020/07/29 Javascript
解决node修改后需频繁手动重启的问题
2018/05/13 Javascript
玩转vue的slot内容分发
2018/09/22 Javascript
Vue使用watch监听一个对象中的属性的实现方法
2019/05/10 Javascript
[43:18]NB vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.22
2019/09/05 DOTA
python实现备份目录的方法
2015/08/03 Python
在IPython中进行Python程序执行时间的测量方法
2018/11/01 Python
python 返回列表中某个值的索引方法
2018/11/07 Python
Python两台电脑实现TCP通信的方法示例
2019/05/06 Python
用python画一只可爱的皮卡丘实例
2019/11/21 Python
解析PyCharm Python运行权限问题
2020/01/08 Python
Django密码存储策略分析
2020/01/09 Python
Python中使用socks5设置全局代理的方法示例
2020/04/15 Python
Python如何避免文件同名产生覆盖
2020/06/09 Python
全球销量第一生发产品:Viviscal
2017/12/21 全球购物
Raleigh兰令自行车美国官网:英国凤头牌自行车
2018/01/08 全球购物
JAVA的事件委托机制和垃圾回收机制
2014/09/07 面试题
《春雨》教学反思
2014/04/24 职场文书
机械系毕业生求职信
2014/05/28 职场文书
MySQL8.0无法启动3534的解决方法
2021/06/03 MySQL
mongodb数据库迁移变更的解决方案
2021/09/04 MongoDB