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转换字符串为摩尔斯电码的方法
Jul 06 Python
django 按时间范围查询数据库实例代码
Feb 11 Python
python生成九宫格图片
Nov 19 Python
对pandas写入读取h5文件的方法详解
Dec 28 Python
在pycharm 中添加运行参数的操作方法
Jan 19 Python
详解Django+uwsgi+Nginx上线最佳实战
Mar 14 Python
Django Form 实时从数据库中获取数据的操作方法
Jul 25 Python
python+Django+pycharm+mysql 搭建首个web项目详解
Nov 29 Python
使用python创建生成动态链接库dll的方法
May 09 Python
pandas数据处理之绘图的实现
Jun 15 Python
tensorflow2.0教程之Keras快速入门
Feb 20 Python
Python常遇到的错误和异常
Nov 02 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具体实现代码
2010/10/12 PHP
php生成excel列序号代码实例
2013/12/24 PHP
php计算指定目录下文件占用空间的方法
2015/03/13 PHP
Laravel 5框架学习之表单验证
2015/04/08 PHP
phalcon框架使用指南
2016/02/23 PHP
php的无刷新操作实现方法分析
2020/02/28 PHP
jQuery 使用手册(二)
2009/09/23 Javascript
ListBox实现上移,下移,左移,右移的简单实例
2014/02/13 Javascript
jQuery中change事件用法实例
2014/12/26 Javascript
JS网页在线获取鼠标坐标值的方法
2015/02/28 Javascript
AngularJS入门教程之MVC架构实例分析
2016/11/01 Javascript
bootstrap动态添加面包屑(breadcrumb)及其响应事件的方法
2017/05/25 Javascript
基于js 各种排序方法和sort方法的区别(详解)
2018/01/03 Javascript
基于nodejs的雪碧图制作工具的示例代码
2018/11/05 NodeJs
jQuery访问json文件中数据的方法示例
2019/01/28 jQuery
JS异步执行结果获取的3种解决方式
2019/02/19 Javascript
swiper Scrollbar滚动条组件详解
2019/09/08 Javascript
解决vuecli3中img src 的引入问题
2020/08/04 Javascript
js实现点击按钮随机生成背景颜色
2020/09/05 Javascript
[01:07:22]2014 DOTA2华西杯精英邀请赛 5 24 DK VS VG加赛
2014/05/26 DOTA
[02:51]DOTA2 2015国际邀请赛中国区预选赛第一日战报
2015/05/27 DOTA
Python开发如何在ubuntu 15.10 上配置vim
2016/01/25 Python
python调用OpenCV实现人脸识别功能
2018/05/25 Python
python实现简易数码时钟
2021/02/19 Python
Python优秀开源项目Rich源码解析的流程分析
2020/07/06 Python
python 进程池pool使用详解
2020/10/15 Python
Python实现Kerberos用户的增删改查操作
2020/12/14 Python
一个入门级python爬虫教程详解
2021/01/27 Python
马来西亚在线时尚女装商店:KEI MAG
2017/09/28 全球购物
彪马法国官网:PUMA法国
2019/12/15 全球购物
银行存款证明样本
2014/01/17 职场文书
投资合作协议书范本
2014/04/17 职场文书
2014年社区国庆节活动方案
2014/09/16 职场文书
2014年环保工作总结
2014/11/26 职场文书
公司仓库管理制度
2015/08/04 职场文书
不知如何爱孩子,这些方法教会您
2019/08/06 职场文书