python类中super() 的使用解析


Posted in Python onDecember 19, 2019

描述

super() 函数是用于调用父类(超类)的一个方法。

super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。

语法

以下是 super() 方法的语法:

super(type[, object-or-type])

Python中类的初始化都是__init__(), 所以父类和子类的初始化方式都是__init__(), 但是如果子类初始化时没有这个函数,那么他将直接调用父类的__init__(); 如果子类指定了__init__(), 就会覆盖父类的初始化函数__init__(),如果想在进行子类的初始化的同时也继承父类的__init__(), 就需要在子类中显示地通过super()来调用父类的__init__()函数。

super()在单继承中的应用:

举个例子:

class Animal: #定义一个父类
  def __init__(self): #父类的初始化
    self.name = 'animal'
    self.role = 'parent'
    print('I am father')

class Dog(Animal): #定一个继承Animal的子类
  def __init__(self): #子类的初始化函数,此时会覆盖父类Animal类的初始化函数
    print('I am son')
    self.name = 'dog' #定义子类的name属性
    super(Dog,self).__init__() #在子类进行初始化时,也想继承父类的__init__()就通过super()实现
    #self.name = 'dog' #若将name属性的定义(即第10行)放在这儿,最终输出将是dog
    
animal = Animal()
xbai = Dog()
print(xbai.name)
print(xbai.role)

输出为:

I am father #实例化Animal类后的输出
I am son #实例化Dog类后的输出
I am father #实例化Dog类后的输出
animal #由于子类初始化是在进行继承父类初始化之前,因此super()执行后,Dog类的name属性被父类覆盖
parent #继承了父类的role属性

说明:super(Dog,self)也可以写成super(),可以理解成super(Dog,self).__init__() == Animal.__init__(self),( super(Dog,self) == Animal ) 即其返回的是当前类的继承顺序中(针对多继承)Dog后的一个类(也即类Animal)

self 和 super的区别:

  • self会首先调用自己的方法或者属性,当自身没有目标属性或方法时,再去父类中寻找;super会直接去父类中寻找目标属性或方法。如上述代码中定义完第十行后,self.name的返回值为'dog',而super().name的返回值为'animal';
  • self时类,super是预编译指令

super()在多继承中的应用:

代码例子:

class Base(object): #定义父类
  def __init__(self):
    print('Base create')
class ChildA(Base): #子类A
  def __init__(self):
    print('Enter A')
    super(ChildA,self).__init__()
    print('Leave A')
class ChildB(Base):
  def __init__(self):
    print('Enter B')
    super(ChildB,self).__init__()
    self.name = 'B'
    print('Leave B')
class ChildC(ChildA,ChildB):#在继承时,按照继承顺序返回继承顺序的下一个类
  pass
## (这里需要介绍的是,当类继承多个类时,python3中是按照广度优先算法,即在类ChildC的继承关系中,会先找到靠近其的基类ChildA,然后继承其的初始化函数__init__(),就不会再继承ChildB的初始化函数)
c = ChildC() #实例化对象
print(c.__class__.__mro__) #对象c的继承顺序应该是 ChildC---ChildA---ChildB---Base---object

输出结果:

Enter A
Enter B
Base create
Leave B
Leave A
(<class '__main__.ChildC'>, <class '__main__.ChildA'>, <class '__main__.ChildB'>, <class '__main__.Base'>, <class 'object'>)

整个执行过程,当实例化对象c时,按照类的继承顺序,先初始化类ChildC(),由于C中未定义初始化函数__init__(),因此直接调用其继承的基类ChildA的__init__()初始化方法,运行到代码行第8行时,按照继承顺序super(ChildA,self)返回的是类ChildB(),因此,super(ChildA,self).__init__() == ChildB().__init__(self),因此就可以理解产生输出结果的原理。

从super()方法中可以看出,super()的第一个参数可以是继承链(继承顺序)中的任意一个类的名字,也可以不填,不填时第一个参数默认为当前类,即代码第10行 super(ChildA,self).__init__() ==super().__init__(),其返回值为在继承链中输入参数类的下一个类。

结论:

  • super()用来继承基类的属性和方法
  • 单继承时,super().__init__() 和 父类.__init__()实现的功能是类似的
  • super不是父类,而是继承顺序的下一个类
  • super()可以避免重复调用

总结

以上所述是小编给大家介绍的python类中super() 的使用解析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
跟老齐学Python之玩转字符串(2)更新篇
Sep 28 Python
python实现清屏的方法
Apr 30 Python
Python中struct模块对字节流/二进制流的操作教程
Jan 21 Python
Python实现将罗马数字转换成普通阿拉伯数字的方法
Apr 19 Python
EM算法的python实现的方法步骤
Jan 02 Python
python Tkinter版学生管理系统
Feb 20 Python
深入浅析Python 中 is 语法带来的误解
May 07 Python
python 最简单的实现适配器设计模式的示例
Jun 30 Python
pycharm中如何自定义设置通过“ctrl+滚轮”进行放大和缩小实现方法
Sep 16 Python
python3中celery异步框架简单使用+守护进程方式启动
Jan 20 Python
浅谈哪个Python库才最适合做数据可视化
Jun 28 Python
pytorch实现加载保存查看checkpoint文件
Jul 15 Python
在python中计算ssim的方法(与Matlab结果一致)
Dec 19 #Python
用openCV和Python 实现图片对比,并标识出不同点的方式
Dec 19 #Python
Python命令行click参数用法解析
Dec 19 #Python
python3 常见解密加密算法实例分析【base64、MD5等】
Dec 19 #Python
Python定义函数时参数有默认值问题解决
Dec 19 #Python
Python爬取腾讯视频评论的思路详解
Dec 19 #Python
使用Pandas将inf, nan转化成特定的值
Dec 19 #Python
You might like
dede3.1分页文字采集过滤规则详说(图文教程)续二
2007/04/03 PHP
php入门学习知识点八 PHP中for循环基本应用之九九乘法口绝表
2011/07/14 PHP
PHP获取php,mysql,apche的版本信息示例代码
2014/01/16 PHP
php实现留言板功能
2017/03/05 PHP
PHP中strtr与str_replace函数运行性能简单测试示例
2019/06/22 PHP
php redis setnx分布式锁简单原理解析
2020/10/23 PHP
PHP7 foreach() 函数修改
2021/03/09 PHP
jquery1.83 之前所有与异步列队相关的模块详细介绍
2012/11/13 Javascript
JavaScript将Table导出到Excel实现思路及代码
2013/03/13 Javascript
Jquery实现图片放大镜效果的思路及代码(自写)
2013/10/18 Javascript
设为首页和收藏的Javascript代码(亲测兼容IE,Firefox,chrome等浏览器)
2013/11/18 Javascript
jquery实现动态画圆
2014/12/04 Javascript
javascript实现简单的分页特效
2015/08/12 Javascript
jQuery链式调用与show知识浅析
2016/05/11 Javascript
JS中将多个逗号替换为一个逗号的实现代码
2017/06/23 Javascript
bootstrap中selectpicker下拉框使用方法实例
2018/03/22 Javascript
手把手带你搭建一个node cli的方法示例
2020/08/07 Javascript
[07:39]第一届亚洲邀请赛回顾视频
2017/02/14 DOTA
[02:55]2018DOTA2国际邀请赛勇士令状不朽珍藏Ⅲ饰品一览
2018/08/01 DOTA
Python命令行参数解析模块optparse使用实例
2015/04/13 Python
python的keyword模块用法实例分析
2015/06/30 Python
wxPython实现窗口用图片做背景
2018/04/25 Python
Tensorflow使用支持向量机拟合线性回归
2018/09/07 Python
python程序封装为win32服务的方法
2021/03/07 Python
python3中property使用方法详解
2019/04/23 Python
HTML5: Web 标准最巨大的飞跃
2008/10/17 HTML / CSS
大学新生军训个人的自我评价
2013/10/03 职场文书
自荐信不宜过于夸大
2013/11/06 职场文书
给女朋友的道歉信
2014/01/10 职场文书
婚庆公司的创业计划书
2014/01/22 职场文书
学习张丽丽心得体会
2014/09/03 职场文书
预备党员考察表党小组意见
2015/06/01 职场文书
应届生个人的求职(自荐信范文2篇)
2019/08/23 职场文书
浅谈克隆 JavaScript
2021/11/02 Javascript
Win11怎样将锁屏账户头像图片改成动画视频
2021/11/21 数码科技
利用uni-app生成微信小程序的踩坑记录
2022/04/05 Javascript