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的Django框架编写从Google Adsense中获得报表的应用
Apr 17 Python
使用url_helper简化Python中Django框架的url配置教程
May 30 Python
Django的URLconf中使用缺省视图参数的方法
Jul 18 Python
numpy中实现二维数组按照某列、某行排序的方法
Apr 04 Python
python循环定时中断执行某一段程序的实例
Jun 29 Python
Python3内置模块之base64编解码方法详解
Jul 13 Python
纯python进行矩阵的相乘运算的方法示例
Jul 17 Python
python绘制规则网络图形实例
Dec 09 Python
python写文件时覆盖原来的实例方法
Jul 22 Python
python collections模块的使用
Oct 16 Python
Python3中对json格式数据的分析处理
Jan 28 Python
conda安装tensorflow和conda常用命令小结
Feb 20 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
phpmailer在服务器上不能正常发送邮件的解决办法
2014/07/08 PHP
PHP/HTML混写的四种方式总结
2017/02/27 PHP
php静态成员方法和静态的成员属性的使用方法
2017/10/26 PHP
javascript 正则替换 replace(regExp, function)用法
2010/05/22 Javascript
js调用activeX获取u盘序列号的代码
2011/11/21 Javascript
jquery sortable的拖动方法示例详解
2014/01/16 Javascript
JqueryMobile动态生成listView并实现刷新的两种方法
2014/03/05 Javascript
原生js实现模拟滚动条
2015/06/15 Javascript
基于jquery实现百度新闻导航菜单滑动动画
2016/03/15 Javascript
简单理解JavaScript中的封装与继承特性
2016/03/19 Javascript
js验证框架实现代码分享
2016/05/18 Javascript
Bootstrap字体图标无法正常显示的解决方法
2016/10/08 Javascript
Vue.js实战之利用vue-router实现跳转页面
2017/04/01 Javascript
vue仿淘宝订单状态的tab切换效果
2020/06/23 Javascript
vue项目中使用百度地图的方法
2018/06/08 Javascript
vue仿element实现分页器效果
2018/09/13 Javascript
jQuery/JS监听input输入框值变化实例
2019/10/17 jQuery
python通过socket查询whois的方法
2015/07/18 Python
关于Django显示时间你应该知道的一些问题
2017/12/25 Python
python命令行解析之parse_known_args()函数和parse_args()使用区别介绍
2018/01/24 Python
Python3.6使用tesseract-ocr的正确方法
2018/10/17 Python
Python程序暂停的正常处理方法
2019/11/07 Python
Python魔法方法 容器部方法详解
2020/01/02 Python
在TensorFlow中屏蔽warning的方式
2020/02/04 Python
CSS3 border-radius圆角的实现方法及用法详解
2020/09/14 HTML / CSS
澳大利亚香水在线商店:City Perfume
2020/09/02 全球购物
工程建设实施方案
2014/03/14 职场文书
六一儿童节演讲稿
2014/05/23 职场文书
工程学毕业生自荐信
2014/06/14 职场文书
教师节活动总结
2014/08/29 职场文书
2015小学教师年度考核工作总结
2015/05/12 职场文书
行政处罚听证告知书
2015/07/01 职场文书
高二化学教学反思
2016/02/22 职场文书
《实心球》教学反思
2016/02/23 职场文书
最新的离婚协议书范本!
2019/07/02 职场文书
Log4j.properties配置及其使用
2021/08/02 Java/Android