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 相关文章推荐
使用go和python递归删除.ds store文件的方法
Jan 22 Python
python实现的解析crontab配置文件代码
Jun 30 Python
python实现图片彩色转化为素描
Jan 15 Python
Anaconda之conda常用命令介绍(安装、更新、删除)
Oct 06 Python
pytorch 数据处理:定义自己的数据集合实例
Dec 31 Python
Python实现搜索算法的实例代码
Jan 02 Python
Python通过正则库爬取淘宝商品信息代码实例
Mar 02 Python
python将logging模块封装成单独模块并实现动态切换Level方式
May 12 Python
Python DES加密实现原理及实例解析
Jul 17 Python
Python CategoricalDtype自定义排序实现原理解析
Sep 11 Python
python 实现波浪滤镜特效
Dec 02 Python
Flask使用SQLAlchemy实现持久化数据
Jul 16 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
深入for,while,foreach遍历时间比较的详解
2013/06/08 PHP
基于PHP服务端图片生成缩略图的方法详解
2013/06/20 PHP
PHP二维数组排序的3种方法和自定义函数分享
2014/04/09 PHP
JS打开新窗口的2种方式
2013/04/18 Javascript
javaScript array(数组)使用字符串作为数组下标的方法
2013/11/19 Javascript
js charAt的使用示例
2014/02/18 Javascript
js父页面与子页面不同时显示的方法
2014/10/16 Javascript
谈谈JavaScript自定义回调函数
2015/10/18 Javascript
angular.bind使用心得
2015/10/26 Javascript
详解JavaScript对象和数组
2015/12/03 Javascript
基于Bootstrap重置输入框内容按钮插件
2016/05/12 Javascript
微信小程序 require机制详解及实例代码
2016/12/14 Javascript
JavaScript手风琴页面制作
2017/05/17 Javascript
Vue侧滑菜单组件——DrawerLayout
2017/12/18 Javascript
VUE 使用中踩过的坑
2018/02/08 Javascript
vue slot 在子组件中显示父组件传递的模板
2018/03/02 Javascript
浅析webpack-bundle-analyzer在vue-cli3中的使用
2019/10/23 Javascript
nodeJS与MySQL实现分页数据以及倒序数据
2020/06/05 NodeJs
[04:36]DOTA2国际邀请赛 ti3精彩集锦
2013/08/19 DOTA
[01:03]PWL开团时刻DAY6——别打我
2020/11/05 DOTA
python3获取当前文件的上一级目录实例
2018/04/26 Python
Python3.6.0+opencv3.3.0人脸检测示例
2018/05/25 Python
python爬虫之线程池和进程池功能与用法详解
2018/08/02 Python
pygame游戏之旅 添加icon和bgm音效的方法
2018/11/21 Python
OpenCV图像颜色反转算法详解
2019/05/13 Python
Django框架首页和登录页分离操作示例
2019/05/28 Python
在python里创建一个任务(Task)实例
2020/04/25 Python
Python numpy矩阵处理运算工具用法汇总
2020/07/13 Python
HTML 5 标签、属性、事件及浏览器兼容性速查表 附打包下载
2012/10/20 HTML / CSS
HTML5之tabindex属性全面解析
2016/07/07 HTML / CSS
美国领先的眼镜和太阳镜在线零售商:Glasses.com
2019/08/26 全球购物
Hobbs官方网站:英国奢华女性时尚服装
2020/02/22 全球购物
大学生毕业自我鉴定
2013/11/06 职场文书
公司晚会主持词
2014/03/22 职场文书
婚假请假条怎么写
2014/04/10 职场文书
恶魔之树最顶端的三颗果实 震震果实上榜,第一可以制造岩浆
2022/03/18 日漫