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 相关文章推荐
python写的ARP攻击代码实例
Jun 04 Python
python根据时间生成mongodb的ObjectId的方法
Mar 13 Python
Python实现把回车符\r\n转换成\n
Apr 23 Python
详解在Python程序中使用Cookie的教程
Apr 30 Python
Python内置函数——__import__ 的使用方法
Nov 24 Python
在Python中增加和插入元素的示例
Nov 01 Python
python使用threading.Condition交替打印两个字符
May 07 Python
Python中单线程、多线程和多进程的效率对比实验实例
May 14 Python
pandas实现将dataframe满足某一条件的值选出
Jun 12 Python
python与c语言的语法有哪些不一样的
Sep 13 Python
python 基于opencv 绘制图像轮廓
Dec 11 Python
Python 实现一个简单的web服务器
Jan 03 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
PHP中遍历stdclass object的实现代码
2011/06/09 PHP
使用PHP编写的SVN类
2013/07/18 PHP
php批量更改数据库表前缀实现方法
2013/10/26 PHP
PHP让数组中有相同值的组成新的数组实例
2017/12/31 PHP
PHP抽象类基本用法示例
2018/12/28 PHP
PHP使用redis位图bitMap 实现签到功能
2019/10/08 PHP
ExtJS 设置级联菜单的默认值
2010/06/13 Javascript
nodejs入门详解(多篇文章结合)
2012/03/07 NodeJs
关于js遍历表格的实例
2013/07/10 Javascript
js中数组(Array)的排序(sort)注意事项说明
2014/01/24 Javascript
JavaSacript中charCodeAt()方法的使用详解
2015/06/05 Javascript
js实现简洁的滑动门菜单(选项卡)效果代码
2015/09/04 Javascript
逐一介绍Jquery data()、Jquery stop()、jquery delay()函数(详)
2015/11/04 Javascript
JavaScript位移运算符(无符号) >>> 三个大于号 的使用方法详解
2016/03/31 Javascript
Javascript中字符串和数字的操作方法整理
2017/01/22 Javascript
微信小程序 支付功能(前端)的实现
2017/05/24 Javascript
Vue 兄弟组件通信的方法(不使用Vuex)
2017/10/26 Javascript
HTML5+JS+JQuery+ECharts实现异步加载问题
2017/12/16 jQuery
vue 多入口文件搭建 vue多页面搭建的实例讲解
2018/03/12 Javascript
Vue-router 中hash模式和history模式的区别
2018/07/24 Javascript
详解微信小程序-canvas绘制文字实现自动换行
2019/04/26 Javascript
python使用smtplib模块通过gmail实现邮件发送的方法
2015/05/08 Python
pytorch permute维度转换方法
2018/12/14 Python
Python列表的切片实例讲解
2019/08/20 Python
Python变量作用域LEGB用法解析
2020/02/04 Python
英国最大的电脑零售连锁店集团:PC World
2016/10/10 全球购物
找到您丢失的钥匙、钱包和手机:Tile
2017/05/19 全球购物
怀俄明州飞钓:Platte River Fly Shop
2017/12/28 全球购物
现代生活方式的家具和装饰:Dot & Bo
2018/12/26 全球购物
公司委托书格式范文
2014/04/04 职场文书
大学优秀班集体申报材料
2014/05/23 职场文书
爱鸟护鸟的宣传语
2015/07/13 职场文书
化工厂员工工作总结
2015/10/15 职场文书
《陶罐和铁罐》教学反思
2016/03/03 职场文书
pyqt5蒙版遮罩mask,setmask的使用
2021/06/11 Python
详解jQuery的核心函数和事件处理
2022/02/18 jQuery