解决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群发邮件实例代码
Jan 03 Python
Python中处理字符串的相关的len()方法的使用简介
May 19 Python
Python中的time模块与datetime模块用法总结
Jun 30 Python
python 文件操作删除某行的实例
Sep 04 Python
python 请求服务器的实现代码(http请求和https请求)
May 25 Python
Python实现的tcp端口检测操作示例
Jul 24 Python
实例介绍Python中整型
Feb 11 Python
Python 互换字典的键值对实例
Feb 12 Python
python爬取盘搜的有效链接实现代码
Jul 20 Python
python json.dumps中文乱码问题解决
Apr 01 Python
使用python批量修改XML文件中图像的depth值
Jul 22 Python
pygame面向对象的飞行小鸟实现(Flappy bird)
Apr 01 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 编写的日历
2006/10/09 PHP
模拟OICQ的实现思路和核心程序(二)
2006/10/09 PHP
PHP Undefined index报错的修复方法
2011/07/17 PHP
php线性表顺序存储实现代码(增删查改)
2012/02/16 PHP
php输出xml必须header的解决方法
2014/10/17 PHP
PHP中Http协议post请求参数
2015/11/02 PHP
Yii2框架实现注册和登录教程
2016/09/30 PHP
Laravel基础_关于view共享数据的示例讲解
2019/10/14 PHP
Google AJAX 搜索 API实现代码
2010/11/17 Javascript
再次分享18个非常棒的jQuery表格插件
2011/04/10 Javascript
修改js Calendar日历控件 兼容IE9/谷歌/火狐
2013/01/04 Javascript
js生成随机数之random函数随机示例
2013/12/20 Javascript
通过node-mysql搭建Windows+Node.js+MySQL环境的教程
2016/03/01 Javascript
vuejs使用$emit和$on进行组件之间的传值的示例
2017/10/04 Javascript
原生js的ajax和解决跨域的jsonp(实例讲解)
2017/10/16 Javascript
基于vue 开发中出现警告问题去除方法
2018/01/25 Javascript
解决layui table表单提示数据接口请求异常的问题
2019/09/24 Javascript
python和shell变量互相传递的几种方法
2013/11/20 Python
几个提升Python运行效率的方法之间的对比
2015/04/03 Python
MySQL适配器PyMySQL详解
2017/09/20 Python
Python推导式简单示例【列表推导式、字典推导式与集合推导式】
2018/12/04 Python
对Python定时任务的启动和停止方法详解
2019/02/19 Python
将python运行结果保存至本地文件中的示例讲解
2019/07/11 Python
python中单下划线(_)和双下划线(__)的特殊用法
2019/08/29 Python
Python3 tkinter 实现文件读取及保存功能
2019/09/12 Python
使用python切片实现二维数组复制示例
2019/11/26 Python
CSS实现鼠标滑过鼠标点击代码写法
2016/12/26 HTML / CSS
应届生财务管理求职信
2013/11/06 职场文书
珍惜资源保护环境的建议书
2014/05/14 职场文书
镇人大副主席民主生活会对照检查材料思想汇报
2014/10/01 职场文书
大学生入党自荐书
2015/03/05 职场文书
《窃读记》教学反思
2016/02/18 职场文书
施工安全协议书
2016/03/22 职场文书
2019公司管理制度
2019/04/19 职场文书
Android使用EventBus发送消息,Fragment中接收消息的方法会执行多次
2022/04/24 Java/Android
Python 图片添加美颜效果
2022/04/28 Python