python的super函数详解

这篇具有很好参考价值的文章主要介绍了python的super函数详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

python基础知识

用于类继承的super函数介绍

目录

python基础知识

一、super函数的用途

二、了解super函数的基本信息

三、多继承不重复调用

 四、多继承重复调用

总结


一、super函数的用途

(1)避免在改动父类名称时还需改动子类调用方法的代码

(2)在子类中按照一套内置的顺序自动调用父类的方法

(3)多用于多继承问题中,解决查找顺序(MRO)、重复调用(钻石继承)等种种问题

二、了解super函数的基本信息

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

函数说明:

        返回一个代理对象,它会将方法调用委托给 type 的父类或兄弟类。

参数说明 :

        type:类,可选参数;

        object-or-type:对象或类,一般是self,也是可选参数;

参数作用:第二个参数决定了调用父类的顺序,比如self,就是调用super函数的对象本身,它有一个__mro__属性,决定了按什么顺序调用父类的方法;第一个参数决定了从哪个类开始调用,一般也可以是本身类,即从本身这个类的顺序中的下一个类开始调用该方法

注:但要注意调用该方法的从始至终都是self对象,而不是父类对象

三、多继承不重复调用

这里我们就直接从多继承开始,明白了多继承super函数的使用,单继承自然也就不在话下。

代码如下:

class A:
    def __init__(self):
        print("找到 funxx() 位于 A 中...")


class B(A):
    def __init__(self):
        print("找到 funxx() 位于 B 中...")


class C(A):
    def __init__(self):
        print("找到 funxx() 位于 C 中...")
    pass


class D(A):
    def __init__(self):
        print("找到 funxx() 位于 D 中...")


class E(B, C):
    def __init__(self):
        print("找到funcxx()位于E中...")


class F(E, D):
    def __init__(self):
        print("执行 F 中的 funff()...")
        super(F, self).__init__()


print(f"F 类的 MRO : {F.__mro__}")#获取得到F类的__mro__属性,从而知道其调用父类的顺序
f = F()

输出如下:

F 类的 MRO : (<class '__main__.F'>, <class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)
执行 F 中的 funff()...
找到funcxx()位于E中...

(1)通过__mro__属性得到F类调用其父类的顺序;即输出的第一行,按照F->E->B->C->D->A类的顺序调用其__init__方法

(2)我们看到super函数内的第二个参数为self对象,所以其按照上述顺序进行调用父类方法;第一个参数为F,即F类,所以我们从F往下开始调用父类方法,这里也就是E类的方法

再次实践(这次我们将super函数的第一个参数改为B):

class A:
    def __init__(self):
        print("找到 funxx() 位于 A 中...")


class B(A):
    def __init__(self):
        print("找到 funxx() 位于 B 中...")


class C(A):
    def __init__(self):
        print("找到 funxx() 位于 C 中...")
    pass


class D(A):
    def __init__(self):
        print("找到 funxx() 位于 D 中...")


class E(B, C):
    def __init__(self):
        print("找到funcxx()位于E中...")


class F(E, D):
    def __init__(self):
        print("执行 F 中的 funff()...")
        super(B, self).__init__()


print(f"F 类的 MRO : {F.__mro__}")#获取得到F类的__mro__属性,从而知道其调用父类的顺序
f = F()

显然就应该调用该顺序中B类的下一个类C类的方法;输出如下:

F 类的 MRO : (<class '__main__.F'>, <class '__main__.E'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.A'>, <class 'object'>)
执行 F 中的 funff()...
找到 funxx() 位于 C 中...

 四、多继承重复调用

先看调用父类方法的普通使用:直接用类名.方法即可;但是在父类名字变化时还得回到子类去做相应修改,很麻烦

class A:
    def __init__(self):
        print("打印属性 a")


class B(A):
    def __init__(self):
        print("打印属性 b")
        A.__init__(self)  # super() 等同于 super(B, self)


class C(A):
    def __init__(self):
        print("打印属性 c")
        A.__init__(self)  # super() 等同于 super(C, self)


class D(B, C):
    def __init__(self):
        print("打印属性 d")
        B.__init__(self)
        C.__init__(self)

d = D()

#以下为输出结果
打印属性 d
打印属性 b
打印属性 a
打印属性 c
打印属性 a

可以看到A的构造函数重复调用了两次,造成资源浪费

再来看看使用super函数进行调用父类的方法

class A:
    def __init__(self):
        print("打印属性 a")

#
class B(A):
    def __init__(self):
        print("打印属性 b")
        super().__init__()  # super() 等同于 super(B, self)


class C(A):
    def __init__(self):
        print("打印属性 c")
        super().__init__()  # super() 等同于 super(C, self)


class D(B, C):
    def __init__(self):
        print("打印属性 d")
        super(D, self).__init__()

d = D()

#输出结果
打印属性 d
打印属性 b
打印属性 c
打印属性 a

(1)强调一下:这里的super()没有参数,就默认都采用了本身类;比如A中的super()相当于super(A,self)

(2)在讲解一下整个程序的运行过程:初始化d对象,打印“打印属性 d”;然后super函数运行,调用了D类的__init__方法,但是这个self是d对象,所以这个顺序一直都是d对象的__mro__属性;打印“打印属性 b”;再调用super函数,按照d对象给出的顺序,下一个是C类的__init__方法,打印“打印属性 c”;继续调用super函数,最后才是A类的__init__方法,打印“打印属性 a”。


总结

以上就是关于super函数的使用讲解,谢谢大家;其中的代码来自(144条消息) Python super( ) 函数详解_小皇鱼的博客-CSDN博客_python super();但是讲解还是自己一个字一个字敲的。文章来源地址https://www.toymoban.com/news/detail-659431.html

到了这里,关于python的super函数详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 详解Python中的split()函数的使用方法

    函数:split() Python中有split()和os.path.split()两个函数,具体作用如下: split():拆分字符串。通过指定分隔符对字符串进行切片,并返回分割后的字符串列表(list) os.path.split():按照路径将文件名和路径分割开 一、函数说明 1、split()函数 语法:str.split(str=\\\"\\\",num=string.count(str))

    2024年02月07日
    浏览(16)
  • 终于搞懂了 super(XXXX, self).__init__()的作用是啥了

    在使用pytorch框架时,难免要自己定义网络。于是, super(XXXX, self). init () ,就成了自定义网络结构时 必不可少 的第一句。但是,super(XXXX, self). init ()具体的作用是什么我一直没有搞清楚。阅读了大量的博客后,我终于搞懂了! 一言以蔽之:super(XXX, self).init()——对继承自父类

    2023年04月08日
    浏览(49)
  • memcmp函数详解 看这一篇就够了-C语言(函数讲解、函数实现、使用用法举例、作用、自己实现函数 )

    memcmp函数详解 看这一篇就够了-C语言(函数讲解、函数实现、使用用法举例、作用、自己实现函数 )

    memcmp()函数用于:比较两个内存块 函数声明:int memcmp ( const void * ptr1, const void * ptr2, size_t num ); 参数: ptr1:指向内存块的指针。 ptr2:指向内存块的指针。 数字:要比较的字节数。 返回值: 0: 在两个内存块中不匹配的第一个字节在  ptr1  中的值低于 在 ptr2  中的值(如果计

    2023年04月09日
    浏览(15)
  • strstr函数详解 看这一篇就够了-C语言(函数讲解、函数实现、使用用法举例、作用、自己实现函数 )

    strstr函数详解 看这一篇就够了-C语言(函数讲解、函数实现、使用用法举例、作用、自己实现函数 )

     strstr()函数用于:查找子字符串 目录 函数介绍 用法示例 函数讲解 实现函数  事例展示 函数声明:char *strstr(const char *str1, const char *str2) 头  文  件:#include string.h 返  回  值: 返回值为char * 类型( 返回指向  str1  中第一次出现的  str2  的指针);如果  str2  不是 

    2024年02月13日
    浏览(11)
  • Python 函数和变量作用域

    Python 函数和变量作用域

    Python 引用变量的顺序:当前作用域局部变量-外层作用域变量-当前模块中的全局变量-Python内置变量。 1、 global global 用来在函数或其他局部作用域中使用全局变量,如果不对全局变量进行修改,那么可以不使用global;如果想要在函数或局部作用域中对全局变量进

    2024年04月24日
    浏览(9)
  • 【Python】学习Python常用函数作用和用法

    1.函数 ​ 函数就是把程序进行打包,封装到一个包中,使用时可以直接进行调用 1.创建函数和调用函数: 2.创建传参函数 3.函数的返回值 ​ return:直接返回值,不在理会后面的所有的代码 4.位置参数 在使用传参函数中有两种关键称呼: ​ 形式参数(形参):在创建函数时

    2024年02月15日
    浏览(15)
  • python中的dropna()函数的作用

    在Python中, dropna() 是一个Pandas库中的函数,用于从数据框(DataFrame)中删除包含缺失值(NaN)的行或列。它用于数据清洗和预处理阶段,以便去除缺失值,使数据更加规整。 dropna() 函数的语法如下: 参数说明: axis :可选参数,表示删除行还是列。默认值为0,表示删除包含

    2024年02月07日
    浏览(8)
  • Python名称空间和作用域,闭包函数

    名称的查询顺序 名称空间的作用域 global和nonlocal的使用 函数对象(函数名) 函数的嵌套调用 函数的嵌套定义 闭包函数

    2024年02月09日
    浏览(8)
  • python 函数-06-变量&参数内存管理及作用域

    python的参数传递,传递的是参数值而非参数地址。参数值被复制后传递进函数。 对于数值类型的参数(即不可变类型,整型、浮点、复数等),在函数内改变参数值,函数外面不受影响。 对于容器类型的参数(即可变类型,列表、字典、字符串等),在函数内改变了容器里

    2024年02月22日
    浏览(14)
  • 05-python之函数-函数的定义/函数的参数/函数返回值/函数说明文档/函数的嵌套使用/函数变量的作用域

    05-python之函数-函数的定义/函数的参数/函数返回值/函数说明文档/函数的嵌套使用/函数变量的作用域

    对应输出如上,没有使用len()函数,对应的子算出字符的长度,但是代码整体写的就很别扭。代码过于重复,代码中唯一不一样的地方就是被统计的字符串不同。同时对应的,代码整体也就会比较低效。可以使用函数,优化过程,先定义函数。 同样的输出,效果一样,两者

    2024年01月19日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包