首页 > 编程语言 >Python super() 详解 最简单的解释

Python super() 详解 最简单的解释

时间:2022-12-15 17:45:12浏览次数:50  
标签:__ Python self ---- init 详解 super class

首先提一下,经典类和新式类。在Python2中,如果定义类的方式是 class MyClass: 那么该类叫做经典类,如果定义类的方式为class MyClass(object): 那么该类为新式类。在Python3中,上面两种方式定义出来的类都叫新式类。本文是基于新式类来进行讲解的。

正文:

Python 中的 super() 是用于调用父类(或父类的父类...)方法的 函数,主要用于多继承,单继承问题不大。下面是一个多继承实例,继承关系为菱形继承, 仔细观察下面三个实例:

 

 

 

 1 #coding=utf-8
 2 #实例一:
 3 class A(object):
 4     def __init__(self):
 5         print("class ---- A ----")
 6  
 7 class B(A):
 8     def __init__(self):
 9         print("class ---- B ----")
10         super(B, self).__init__()
11  
12 class C(A):
13     def __init__(self):
14         print("class ---- C ----")
15         super(C, self).__init__()
16  
17 class D(B, C):
18     def __init__(self):
19         print("class ---- D ----")
20         super(D, self).__init__()
21  
22 d = D()
23 '''
24 #输出结果:
25 class ---- D ----
26 class ---- B ----
27 class ---- C ----
28 class ---- A ----
29 '''
 1 #coding=utf-8
 2 #实例二: 更改一下类D的super函数:
 3 class D(B, C):
 4     def __init__(self):
 5         print("class ---- D ----")
 6         super(B, self).__init__()
 7  
 8 d = D()
 9 '''
10 #输出结果:
11 class ---- D ----
12 class ---- C ----
13 class ---- A ----
14 '''
 1 # 实例三: 再更改一下类D的super函数:
 2 class D(B, C):
 3     def __init__(self):
 4         print("class ---- D ----")
 5         super(C, self).__init__()
 6  
 7 d = D()
 8 '''
 9 # 输出结果:
10 class ---- D ----
11 class ---- A ----
12 '''

如果你认为 super() 函数就是 调用父类的方法,那你可能想不通后面两个实例。原因是,super() 和父类没有实质性的关联。如果想要搞懂super() 函数的运行原理,那一定要先搞懂 __mro__ 属性, __mro__ 是Method Resolution Order,中文方法解析顺序。单继承中super() 函数使用比较简单的原因 也是因为 __mro__ 比较简单,多继承的__mro__就稍微复杂了,总之 __mro__的目的就是 按照一定顺序,保证父类的函数只调用一次。

我们来先打印一下 它的属性值,再次修改类D的super函数:

 1 class D(B, C):
 2     def __init__(self):
 3         print(D.__mro__)
 4         print("class ---- D ----")
 5         super(D, self).__init__()
 6  
 7 d = D()
 8  
 9 '''
10 #输出结果:
11 (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
12 class ---- D ----
13 class ---- B ----
14 class ---- C ----
15 class ---- A ----
16 '''

从打印结果可以看出,__mro__是一个元组,类D的__mro__顺序是 D -> B -> C -> A -> object。敲黑板(重点):如果在类D中 调用super()函数时 传入的第一个参数是D,那么super() 函数就会在__mro__ 里从D的上一级开始查找,它的上一级是B, 那么super(D, self).__init__() 就调用B的__init__()函数,B的__init__()函数里又调用了B的super()函数,super(B, self).__init__(), 那就从B的上一级再开始查找,B的上一级是C, 以此类推,然后是A,最后是object。于是实例一也就解释清楚了。

实例二中 类D的super() 方法第一个参数传入的是 B ,那么根据__mro__顺序开始查找,B的上一级是C,C的上一级是A,所以实例二的打印顺序是 D - > C -> A

实例三也就不难解释了。

最后再讲一下 super()函数的参数,该函数需要两个参数,第一个是类名,第二个一般都是self,但偶尔也有cls的情况,在:Python 3 可以使用直接使用 super() .xxx 代替 super(Class, self).xxx, 比如:

 1 class D(B, C):
 2     def __init__(self):
 3         print(D.__mro__)
 4         print("class ---- D ----")
 5         super().__init__()
 6 d = D()
 7 '''
 8 #输出结果:
 9 (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
10 class ---- D ----
11 class ---- B ----
12 class ---- C ----
13 class ---- A ----
14 '''

再回到文章的开始,谈一下经典类和新式类:

经典类的MRO方法是采用 从左至右的深度优先遍历 算法,重复留前者

按照深度遍历,其顺序为 [D, B, A, object, C, A, object],重复者只保留前面一个,因此变为 [D, B, A, object, C]

新式类的MRO方法是采用 从左至右的深度优先遍历 的算法,重复留后者

按照深度遍历,其顺序为 [D, B, A, object, C, A, object],重复者只保留后面一个,因此变为 [D, B, C, A, object]
————————————————
版权声明:本文为CSDN博主「芝士锅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wanzew/article/details/106993425

 

标签:__,Python,self,----,init,详解,super,class
From: https://www.cnblogs.com/sunzhiqi/p/16985677.html

相关文章

  • python使用遍历文件夹文件
    python使用遍历文件夹文件一,遍历函数os.walk(rootdir):#返回三个参数:分别返回1.父目录2.所有文件夹名字(不含路径)3.所有文件名字二,使用importosimportos.pa......
  • 二、memcache 启动参数详解
    memcache启动参数:(以最新1.6.17为例)memcache--help命令提示点击查看代码memcached1.6.17-p,--port=<num>小写p,memcached监听的tcp端口。(默认端口为11211)......
  • 【Python多任务--进程,协程】
    一、进程进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。进程是线程的容器,一个进程可以有多个线程进程特......
  • 【Python多任务--进程池Pool】
    进程池Pool在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocess......
  • Python算法题
    2.11斐波那契数列1、1、2、3、5、8、13.....已知一个数列:1、1、2、3、5、8、13、。。。。的规律为从3开始的每一项都等于其前两项的和,这是斐波那契数列。求满足规律的......
  • python的元组详解
    names=["zhangsan","lisi","wangwu","zhaoliu"]#从元组中取出来元素print(names[0:3])#打印第0个到第2个元组,取左不取右print(names[-1])#打印元组的最后一个元素#添加元......
  • 使用python爬取微博评论
    最近在复习以前学习的python爬虫内容,就拿微博来练了一下手,这个案例适合学习爬虫到中后期的小伙伴,因为他不是特别简单也不是很难,关键是思路,为什么说不是很难呢?因为还没涉及......
  • Linux inode详解
    1、inode和block概述block:操作系统在读取硬盘的时候,会一次性读取一“块”(block),这种块是文件存取的最小的单位,block的大小常见的是4KB,即八个扇区构成。(硬盘的最小存储单位......
  • python视频传输方案
    1.1:imageZMQ库实现,发送端importsocketimporttimeimportcv2importimagezmqimporttracebackimportsimplejpegcapture=cv2.VideoCapture(0)#获取摄像头视频c......
  • python安装pyqt的相关经验
    1:pipinstallPyQt5-ihttps://pypi.douban.com/simple首先安装PyQt5的包;2:pipinstallPyQt5-tools-ihttps://pypi.douban.com/simple这个包需要安......