python类中super() 的使用解析

作者:larryli007 时间:2022-12-02 09:08:10 

描述

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() 的使用解析网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

来源:https://blog.csdn.net/larryli007/article/details/83476441

标签:python,super()
0
投稿

猜你喜欢

  • 浅谈SQL Server 2016里TempDb的进步

    2024-01-13 20:23:41
  • 教你用Python读取CSV文件的5种方式

    2022-12-11 15:32:51
  • 使用Dajngo 通过代码添加xadmin用户和权限(组)

    2021-08-07 17:43:59
  • SQL2005 服务器因重装改名后出错的说明

    2024-01-23 09:31:22
  • 使用ASP实现广告代理

    2010-05-27 12:15:00
  • Python教程之类型转换详解

    2021-03-23 02:48:17
  • SQLServer中bigint转int带符号时报错问题解决方法

    2024-01-16 00:13:01
  • 关于Mysql5.7及8.0版本索引失效情况汇总

    2024-01-21 08:35:35
  • 一篇文章教你用Python实现一键文件重命名

    2022-09-21 20:18:38
  • python中torch.nn.identity()方法详解

    2021-05-21 16:51:01
  • Python的装饰器用法学习笔记

    2021-05-06 03:03:36
  • ASP.NET数据库操作类实例

    2024-01-12 21:01:07
  • GoLang基础学习之go test测试

    2024-02-06 16:28:19
  • 详解利用OpenCV提取图像中的矩形区域(PPT屏幕等)

    2022-06-23 16:42:41
  • 在python plt图表中文字大小调节的方法

    2021-04-21 04:40:28
  • Python中标准库OS的常用方法总结大全

    2021-04-29 06:43:41
  • jupyter notebook内核配置的图文教程

    2023-11-22 03:56:56
  • asp如何最大限度地实现安全登录功能?

    2010-07-11 21:11:00
  • python scipy求解非线性方程的方法(fsolve/root)

    2022-01-06 15:46:00
  • 使用tensorflow框架在Colab上跑通猫狗识别代码

    2022-04-27 04:43:39
  • asp之家 网络编程 m.aspxhome.com