Python高级编程之继承问题详解(super与mro)


Posted in Python onNovember 19, 2019

本文实例讲述了Python高级编程之继承问题。分享给大家供大家参考,具体如下:

多继承问题

1.单独调用父类:

一个子类同时继承自多个父类,又称菱形继承、钻石继承。

使用父类名.init(self)方式调用父类时:

例:

class Parent(object):
  def __init__(self, name):
    self.name = name
    print('parent的init结束被调用')
class Son1(Parent):
  def __init__(self, name, age):
    Parent.__init__(self, name)
    self.age = age
    print('Son1的init结束被调用')
class Son2(Parent):
  def __init__(self, name, gender):
    Parent.__init__(self, name)
    self.gender = gender
    print('Son2的init结束被调用')
class Grandson(Son1, Son2):
  def __init__(self, name, age, gender):
    Son1.__init__(self, name, age) # 单独调用父类的初始化方法
    Son2.__init__(self, name, gender)
    print('Grandson的init结束被调用')
gs = Grandson('grandson', 12, '男')

执行结果:

Python高级编程之继承问题详解(super与mro)

可以看出使用父类名.init(self)方式调用父类时,parent父类被调用了两次,此方法对于多继承不太合适。

2.MRO顺序:

上述代码,我们发现由于多继承情况,parent类被的属性被构造了两次,如果在更加复杂的结构下可能更加严重。

为了解决这个问题,Python官方采用了一个算法将复杂结构上所有的类全部都映射到一个线性顺序上,而根据这个顺序就能够保证所有的类都会被构造一次。

这个顺序就是MRO顺序。

MRO顺序采用C3算法广度优先遍历。

使用方法: 类名.mro()或类名.mro()

Python高级编程之继承问题详解(super与mro)

3.super调用父类:

使用super().init()方式调用父类时:

例:

class Parent(object):
  def __init__(self, name, *args, **kwargs): # 为避免多继承报错,使用不定长参数,接受参数
    self.name = name
    print('parent的init结束被调用')
class Son1(Parent):
  def __init__(self, name, age, *args, **kwargs): # 为避免多继承报错,使用不定长参数,接受参数
    self.age = age
    super().__init__(name, *args, **kwargs) # 为避免多继承报错,使用不定长参数,接受参数
    print('Son1的init结束被调用')
class Son2(Parent):
  def __init__(self, name, gender, *args, **kwargs): # 为避免多继承报错,使用不定长参数,接受参数
    self.gender = gender
    super().__init__(name, *args, **kwargs) # 为避免多继承报错,使用不定长参数,接受参数
    print('Son2的init结束被调用')
class Grandson(Son1, Son2):
  def __init__(self, name, age, gender):
    # 多继承时,相对于使用类名.__init__方法,要把每个父类全部写一遍
    # 而super只用一句话,执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因
    # super(Grandson, self).__init__(name, age, gender)
    super().__init__(name, age, gender)
    print('Grandson的init结束被调用')
gs = Grandson('grandson', 12, '男')
print(Grandson.__mro__)

运行结果:

Python高级编程之继承问题详解(super与mro)

parent父类只被调用了一次,super方法会按照MRO顺序调用下一个父类。

总结:

(1)MRO保证了多继承情况 每个类只出现一次

(2)super().init相对于类名.init,在单继承上用法基本无差

(3)但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次

(4)多继承时,使用super方法,对父类的传参数,是由于python中super的算法导致的原因,必须把参数全部传递,否则会报错

(5)单继承时,使用super方法,不能全部传递,只能传父类方法所需的参数,否则会报错

(6)多继承时,相对于使用类名.init方法,要把每个父类全部写一遍, 而使用super方法,只需写一句话便执行了全部父类的方法,这也是为何多继承需要全部传参的一个原因

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
django开发之settings.py中变量的全局引用详解
Mar 29 Python
利用python操作SQLite数据库及文件操作详解
Sep 22 Python
python实现图片处理和特征提取详解
Nov 13 Python
python pyheatmap包绘制热力图
Nov 09 Python
Python中将两个或多个list合成一个list的方法小结
May 12 Python
python文件选择对话框的操作方法
Jun 27 Python
python基于TCP实现的文件下载器功能案例
Dec 10 Python
python 中值滤波,椒盐去噪,图片增强实例
Dec 18 Python
Pytorch Tensor 输出为txt和mat格式方式
Jan 03 Python
python入门教程之基本算术运算符
Nov 13 Python
jupyter notebook更换皮肤主题的实现
Jan 07 Python
python中Tkinter 窗口之输入框和文本框的实现
Apr 12 Python
Python3 Tkinkter + SQLite实现登录和注册界面
Nov 19 #Python
Python csv文件的读写操作实例详解
Nov 19 #Python
Python高级property属性用法实例分析
Nov 19 #Python
wxPython之wx.DC绘制形状
Nov 19 #Python
python matplotlib拟合直线的实现
Nov 19 #Python
Python线程指南分享
Nov 19 #Python
wxpython+pymysql实现用户登陆功能
Nov 19 #Python
You might like
二次元帅气男生排行榜,只想悄悄收藏系列
2020/03/04 日漫
基于php实现的验证码小程序
2016/12/13 PHP
phpStudy中升级MySQL版本到5.7.17的方法步骤
2017/08/03 PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
2018/02/07 PHP
php实现等比例压缩图片
2018/07/26 PHP
JS与框架页的操作代码
2010/01/17 Javascript
如何使用jquery动态加载js,css文件实现代码
2013/04/03 Javascript
Jquery中val()表单取值赋值的实例代码
2013/08/15 Javascript
基于jquery扩展漂亮的CheckBox(自己编写)
2013/11/19 Javascript
js实现局部页面打印预览原理及示例代码
2014/07/03 Javascript
javascript轻量级库createjs使用Easel实现拖拽效果
2016/02/19 Javascript
node.js使用cluster实现多进程
2016/03/17 Javascript
js实现简单的网页换肤效果
2017/01/18 Javascript
Vue声明式渲染详解
2017/05/17 Javascript
JavaScript输出所选择起始与结束日期的方法
2017/07/12 Javascript
javaScript中的空值和假值
2017/12/18 Javascript
Mac下安装vue
2018/04/11 Javascript
JavaScript使用小插件实现倒计时的方法讲解
2019/03/11 Javascript
微信小程序 函数防抖 解决重复点击消耗性能问题实现代码
2019/09/12 Javascript
微信小程序错误this.setData报错及解决过程
2019/09/18 Javascript
Vue混入mixins滚动触底的方法
2019/11/22 Javascript
[01:14]2014DOTA2展望TI 剑指西雅图newbee战队专访
2014/06/30 DOTA
win10系统中安装scrapy-1.1
2016/07/03 Python
Python基于hashlib模块的文件MD5一致性加密验证示例
2018/02/10 Python
Python3使用turtle绘制超立方体图形示例
2018/06/19 Python
python求最大值,不使用内置函数的实现方法
2019/07/09 Python
django解决订单并发问题【推荐】
2019/07/31 Python
使用python批量修改文件名的方法(视频合并时)
2020/03/24 Python
详解python datetime模块
2020/08/17 Python
学雷锋活动总结范文
2014/04/25 职场文书
工作求职自荐信
2014/06/13 职场文书
2015年采购工作总结
2015/04/10 职场文书
2015年初一班主任工作总结
2015/05/13 职场文书
刑事附带民事诉讼答辩状
2015/05/22 职场文书
《模拟人生4》推出新补丁 “婚礼奇缘”DLC终于得到修复
2022/04/03 其他游戏
Vue 打包后相对路径的引用问题
2022/06/05 Vue.js