解决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编程模板汇总
Feb 12 Python
Python使用logging结合decorator模式实现优化日志输出的方法
Apr 16 Python
解决Django模板无法使用perms变量问题的方法
Sep 10 Python
Python爬虫天气预报实例详解(小白入门)
Jan 24 Python
使用Python进行QQ批量登录的实例代码
Jun 11 Python
python同时遍历数组的索引和值的实例
Nov 15 Python
pyttsx3实现中文文字转语音的方法
Dec 24 Python
python 将字符串中的数字相加求和的实现
Jul 18 Python
更新pip3与pyttsx3文字语音转换的实现方法
Aug 08 Python
使用Python进行中文繁简转换的实现代码
Oct 18 Python
python开发实时可视化仪表盘的示例
May 07 Python
pytorch实现ResNet结构的实例代码
May 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
冰滴咖啡制作步骤
2021/03/03 冲泡冲煮
php获取某个目录大小的代码
2008/09/10 PHP
php用正则表达式匹配URL的简单方法
2013/11/12 PHP
PHP限制页面只能在微信自带浏览器访问的代码
2014/01/15 PHP
使用新浪微博API的OAuth认证发布微博实例
2015/03/27 PHP
Thinkphp实现站点静态化的方法详解
2017/03/21 PHP
PHP实现批量删除(封装)
2017/04/28 PHP
Yii 2.0自带的验证码使用经验分享
2017/06/19 PHP
屏蔽Flash右键信息的js代码
2010/01/17 Javascript
基于jquery实现后台左侧菜单点击上下滑动显示
2013/04/11 Javascript
jquery表单验证框架提供的身份证验证方法(示例代码)
2013/12/27 Javascript
元素未显示设置width/height时IE中使用currentStyle获取为auto
2014/05/04 Javascript
初步了解javascript面向对象
2015/11/09 Javascript
jQuery实现用户输入自动完成功能
2017/02/13 Javascript
关于javascript获取内联样式与嵌入式样式的实例
2017/06/01 Javascript
ubuntu编译nodejs所需的软件并安装
2017/09/12 NodeJs
在vue组件中使用axios的方法
2018/03/16 Javascript
vue项目每30秒刷新1次接口的实现方法
2018/12/04 Javascript
微信小程序获取用户绑定手机号方法示例
2019/07/21 Javascript
微信小程序HTTP请求从0到1封装
2019/09/09 Javascript
深度解读vue-resize的具体用法
2020/07/08 Javascript
Python实现高效求解素数代码实例
2015/06/30 Python
Python常用的爬虫技巧总结
2016/03/28 Python
python实现二维码扫码自动登录淘宝
2016/12/27 Python
用Cython加速Python到“起飞”(推荐)
2019/08/01 Python
Python 调用 Outlook 发送邮件过程解析
2019/08/08 Python
大学在校生求职信范文
2013/11/21 职场文书
高中英语教学反思
2014/02/04 职场文书
学校节能减排倡议书
2014/05/16 职场文书
课外活动总结范文
2014/07/09 职场文书
民警群众路线教育实践活动对照检查材料
2014/10/04 职场文书
个人党性锻炼总结
2015/03/05 职场文书
暑假开始了,你的暑假学习计划写好了吗?
2019/07/04 职场文书
Python 实现定积分与二重定积分的操作
2021/05/26 Python
简述Java中throw-throws异常抛出
2021/08/07 Java/Android
CSS中理解层叠性及权重如何分配
2022/12/24 HTML / CSS