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 相关文章推荐
Python2.x利用commands模块执行Linux shell命令
Mar 11 Python
python实现多线程抓取知乎用户
Dec 12 Python
python中in在list和dict中查找效率的对比分析
May 04 Python
flask入门之表单的实现
Jul 18 Python
Python判断telnet通不通的实例
Jan 26 Python
六行python代码的爱心曲线详解
May 17 Python
在django中实现页面倒数几秒后自动跳转的例子
Aug 16 Python
Python使用Slider组件实现调整曲线参数功能示例
Sep 06 Python
详解Python可视化神器Yellowbrick使用
Nov 11 Python
如何基于Python实现电子邮件的发送
Dec 16 Python
Python3自动生成MySQL数据字典的markdown文本的实现
May 07 Python
Python转换字典成为对象,可以用&quot;.&quot;方式访问对象属性实例
May 11 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
PHP 5.0对象模型深度探索之对象复制
2008/03/27 PHP
利用Memcached在php下实现session机制 替换PHP的原生session支持
2010/08/21 PHP
PHP 自定义错误处理函数的使用详解
2013/05/10 PHP
PHP5.3与5.5废弃与过期函数整理汇总
2014/07/10 PHP
php计算两个文件相对路径的方法
2015/03/14 PHP
php处理多图上传压缩代码功能
2018/06/13 PHP
PHP创建文件及写入数据(覆盖写入,追加写入)的方法详解
2019/02/15 PHP
Thinkphp 3.2框架使用Redis的方法详解
2019/10/24 PHP
零基础学JavaScript最新动画教程+iso光盘下载
2008/01/22 Javascript
JavaScript判断窗口是否最小化的代码(跨浏览器)
2010/08/01 Javascript
setInterval与clearInterval的使用示例代码
2014/01/28 Javascript
网页右侧悬浮滚动在线qq客服代码示例
2014/04/28 Javascript
JavaScript开发人员的10个关键习惯小结
2014/12/05 Javascript
jQuery中attr()与prop()函数用法实例详解(附用法区别)
2015/12/29 Javascript
JavaScript判断表单为空及获取焦点的方法
2016/02/12 Javascript
js 定义对象数组(结合)多维数组方法
2016/07/27 Javascript
微信小程序 http请求的session管理
2017/06/07 Javascript
使用layer模态框给新页面传值的方法
2019/09/27 Javascript
js中Function引用类型常见有用的方法和属性详解
2019/12/11 Javascript
typescript编写微信小程序创建项目的方法
2021/01/29 Javascript
[02:43]DOTA2亚洲邀请赛场馆攻略——带你走进东方体育中心
2018/03/19 DOTA
[54:18]DOTA2-DPC中国联赛 正赛 PSG.LGD vs LBZS BO3 第一场 1月22日
2021/03/11 DOTA
跟老齐学Python之深入变量和引用对象
2014/09/24 Python
Python复制目录结构脚本代码分享
2015/03/06 Python
Python实现二维数组按照某行或列排序的方法【numpy lexsort】
2017/09/22 Python
python 显示数组全部元素的方法
2018/04/19 Python
解决Tensorflow使用pip安装后没有model目录的问题
2018/06/13 Python
Pytorch .pth权重文件的使用解析
2020/02/14 Python
Python json格式化打印实现过程解析
2020/07/21 Python
浅析canvas元素的html尺寸和css尺寸对元素视觉的影响
2019/07/22 HTML / CSS
名企HR怎样看待求职信
2014/02/23 职场文书
组织鉴定材料
2014/06/02 职场文书
党员民主生活会材料
2014/12/15 职场文书
2015年求职自荐信范文
2015/03/04 职场文书
CSS三大特性继承性、层叠性和优先级详解
2022/01/18 HTML / CSS
python获取字符串中的email
2022/03/31 Python