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 相关文章推荐
pygame学习笔记(6):完成一个简单的游戏
Apr 15 Python
python中pass语句用法实例分析
Apr 30 Python
Python设计模式中单例模式的实现及在Tornado中的应用
Mar 02 Python
基于python脚本实现软件的注册功能(机器码+注册码机制)
Oct 09 Python
解决Matplotlib图表不能在Pycharm中显示的问题
May 24 Python
python爬虫 爬取58同城上所有城市的租房信息详解
Jul 30 Python
Python分割训练集和测试集的方法示例
Sep 19 Python
Django实现文件上传下载
Oct 06 Python
Django继承自带user表并重写的例子
Nov 18 Python
Anaconda 查看、创建、管理和使用python环境的方法
Dec 03 Python
利用python汇总统计多张Excel
Sep 22 Python
python 实现的截屏工具
May 08 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
关于我转生变成史莱姆这档事:第二季PV上线,萌王2021年回归
2020/05/06 日漫
PHP脚本的10个技巧(3)
2006/10/09 PHP
PHP 日期时间函数的高级应用技巧
2009/10/10 PHP
基于PHP对XML的操作详解
2013/06/07 PHP
php+mysqli使用预处理技术进行数据库查询的方法
2015/01/28 PHP
PHP基于GD库实现的生成图片缩略图函数示例
2017/07/05 PHP
PHP基于递归算法解决兔子生兔子问题
2018/05/11 PHP
JS随即打乱数组实现代码
2012/12/03 Javascript
url参数中有+、空格、=、%、&、#等特殊符号的问题解决
2013/05/15 Javascript
JS实现图片无间断滚动代码汇总
2014/07/30 Javascript
jQuery实现仿腾讯迷你首页选项卡效果代码
2015/09/17 Javascript
JavaScript创建对象的七种方式(推荐)
2017/06/26 Javascript
使用AngularJS对表单提交内容进行验证的操作方法
2017/07/12 Javascript
使用Dropzone.js上传的示例代码
2017/10/10 Javascript
改进 JavaScript 和 Rust 的互操作性并深入认识 wasm-bindgen 组件
2019/07/13 Javascript
详解微信小程序自定义组件的实现及数据交互
2019/07/22 Javascript
vue实现手机号码的校验实例代码(防抖函数的应用场景)
2019/09/05 Javascript
详解react组件通讯方式(多种)
2020/05/06 Javascript
利用Python将文本中的中英文分离方法
2018/10/31 Python
Python基于plotly模块实现的画图操作示例
2019/01/23 Python
python根据多个文件名批量查找文件
2019/08/13 Python
Python应用实现处理excel数据过程解析
2020/06/19 Python
Python selenium模块实现定位过程解析
2020/07/09 Python
HTML5的结构和语义(2):结构
2008/10/17 HTML / CSS
考试退步检讨书
2014/01/15 职场文书
便利店的创业计划书
2014/01/15 职场文书
幼儿园亲子活动方案
2014/01/29 职场文书
大学秋游活动方案
2014/02/11 职场文书
临床护理求职信
2014/04/26 职场文书
文秘专业应届生求职信
2014/05/26 职场文书
医学生求职自荐书
2014/06/12 职场文书
销售目标责任书
2014/07/23 职场文书
考试作弊检讨书怎么写?
2014/12/21 职场文书
优秀范文:《但愿人长久》教学反思3篇
2019/10/24 职场文书
修改MySQL的数据库引擎为INNODB的方法
2021/05/26 MySQL
python​格式化字符串
2022/04/20 Python