精华内容
下载资源
问答
  • 一、super函数简介 python内置函数super()主要用于类的多继承中,用来查找并调用父类的方法,所以在单重继承中用不用 super 都没关系;但是,使用 super() 是一个好的习惯。一般我们在子类中需要调用父类的方法时才...
  • 主要介绍了Python中super函数的用法,详细的介绍了Python super函数的具体用法和实例,具有一定的参考价值,有兴趣的可以了解一下
  • 主要介绍了Python中super函数用法,结合实例形式详细分析了Python中super函数的功能、调用父类相关原理、操作技巧与注意事项,需要的朋友可以参考下
  • 可能有人会想到,Python中既然可以直接通过父类名调用父类方法为什么还会存在super函数?其实,很多人对Python中的super函数的认识存在误区,本文我们就带来在Python编程中对super函数的正确理解和用法解析
  • 今天小编就为大家分享一篇对Python3之方法的覆盖与super函数详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
  • 彻底搞懂python super函数的作用

    万次阅读 多人点赞 2018-11-15 08:55:23
    super() 的入门使用 在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但...2、使用super函数来调用 先来说下第一种方式:调用未绑定的父类方法。 演示: class Base(object): def greet(self): ...

    super() 的入门使用

    在类的继承中,如果重定义某个方法,该方法会覆盖父类的同名方法,但有时,我们希望能同时实现父类的功能,这时,我们就需要调用父类的方法了。
    调用父类同名方法有两种方式:
    1、调用未绑定的父类方法
    2、使用super函数来调用

    先来说下第一种方式:调用未绑定的父类方法。
    演示:

    class Base(object):
        def greet(self):
            print('hi,I am Base')
    
    class A(Base):
        def greet(self):
            Base.greet(self)  #通过父类Base直接调用greet方法,并把self作为参数
            print('hi,I am A')
    
    
    a=A()
    
    a.greet()
    

    运行结果:

    C:\python36\python.exe E:/demo/testPyQt.py
    hi,I am Base
    hi,I am A
    
    Process finished with exit code 0
    
    

    这种方式简单用还可以,如果在多重继承中就会有问题。
    演示:

    class Base(object):
        def __init__(self):
            print("enter Base")
            print("leave Base")
    
    
    class A(Base):
        def __init__(self):
            print("enter A")
            Base.__init__(self) #调用父类的构造函数进行初始化
            print("leave A")
    
    
    class B(Base):
        def __init__(self):
            print("enter B")
            Base.__init__(self) #调用父类的构造函数进行初始化
            print("leave B")
    
    class C(A,B):
        def __init__(self):
            print("enter C")
            A.__init__(self) #调用父类A的构造函数进行初始化
            B.__init__(self) #调用父类B的构造函数进行初始化
            print("leave C")
    
    
    c=C()
    
    

    运行结果:

    C:\python36\python.exe E:/demo/testPyQt.py
    enter C
    enter A
    enter Base
    leave Base
    leave A
    enter B
    enter Base
    leave Base
    leave B
    leave C
    
    Process finished with exit code 0
    
    

    从上面的运行结果可以看出,基类Base的构造函数被调用了两次,这是有问题的,正常的应该是:A的构造函数调用一次,B的构造函数调用一次,基类Base的构造函数调用一次。
    那么这个问题能不能解决呢,可以的,下面介绍super。
    演示:

    class Animal(object):
        def __init__(self, name):
            self.name = name
    
        def greet(self):
            print('Hello, I am %s.' % self.name)
    
    
    class Dog(Animal):
        def greet(self):
            super(Dog, self).greet()  #调用父类Animal的greet方法
            print('WangWang...')
    
    
    d=Dog("xiaohuang")
    
    d.greet()
    
    
    

    在上面,Animal 是父类,Dog 是子类,我们在 Dog 类重定义了 greet 方法,为了能同时实现父类的功能,我们又调用了父类的方法,运行结果:

    C:\python36\python.exe E:/demo/testPyQt.py
    Hello, I am xiaohuang.
    WangWang...
    
    Process finished with exit code 0
    

    super 的一个最常见用法可以说是在子类中调用父类的初始化方法了。
    演示:

    class Base(object):
        def __init__(self, a, b):
            self.a = a
            self.b = b
    
    
    class A(Base):
        def __init__(self, a, b, c):
            super(A, self).__init__(a, b)  # Python3 可使用 super().__init__(a, b)
            self.c = c
    
    a=A(100,200,300)
    
    print("a=%d, b=%d, c=%d" % (a.a,a.b,a.c))
    

    运行结果:

    C:\python36\python.exe E:/demo/testPyQt.py
    a=100, b=200, c=300
    
    Process finished with exit code 0
    
    

    深入super()

    看了上面的使用,你可能会觉得 super 的使用很简单,无非就是获取了父类,并调用父类的方法。其实,在上面的情况下,super 获得的类刚好是父类,但在其他情况就不一定了,super 其实和父类没有实质性的关联。
    让我们看一个稍微复杂的例子,涉及到多重继承,代码如下:

    class Base(object):
        def __init__(self):
            print("enter Base")
            print("leave Base")
    
    
    class A(Base):
        def __init__(self):
            print("enter A")
            super(A,self).__init__()
            print("leave A")
    
    
    class B(Base):
        def __init__(self):
            print("enter B")
            super(B,self).__init__()
            print("leave B")
    
    class C(A,B):
        def __init__(self):
            print("enter C")
            super(C,self).__init__()
            print("leave C")
    
    
    c=C()
    

    运行结果:

    C:\python36\python.exe E:/demo/testPyQt.py
    enter C
    enter A
    enter B
    enter Base
    leave Base
    leave B
    leave A
    leave C
    
    Process finished with exit code 0
    

    OK,这个运行结果是正常的,类C继承自A,B,而A和B又分别继承类Base,每一个类的构造函数分别被调用了一次。

    如果你认为 super 代表『调用父类的方法』,那你很可能会疑惑为什么 enter A 的下一句不是 enter Base 而是 enter B。原因是,super 和父类没有实质性的关联,现在让我们搞清 super 是怎么运作的。

    MRO列表

    事实上,对于你定义的每一个类,Python 会计算出一个方法解析顺序(Method Resolution Order, MRO)列表,它代表了类继承的顺序,我们可以使用下面的方式获得某个类的 MRO 列表:

    print(C.mro())
    

    运行结果:

    [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]
    

    这个列表真实的列出了类C的继承顺序。C->A->B->Base->object。在方法调用时,是按照这个顺序查找的。
    那这个 MRO 列表的顺序是怎么定的呢,它是通过一个 C3 线性化算法来实现的,这里我们就不去深究这个算法了,感兴趣的读者可以自己去了解一下,总的来说,一个类的 MRO 列表就是合并所有父类的 MRO 列表,并遵循以下三条原则:

    • 子类永远在父类前面
    • 如果有多个父类,会根据它们在列表中的顺序被检查
    • 如果对下一个类存在两个合法的选择,选择第一个父类

    super 原理

    super 的工作原理如下:

    def super(cls, inst):
        mro = inst.__class__.mro()
        return mro[mro.index(cls) + 1]
    

    其中,cls 代表类,inst 代表实例,上面的代码做了两件事:

    • 获取 inst 的 MRO 列表
    • 查找 cls 在当前 MRO 列表中的 index, 并返回它的下一个类,即 mro[index + 1]

    当你使用 super(cls, inst) 时,Python 会在 inst 的 MRO 列表上搜索 cls 的下一个类。
    现在,让我们回到前面的例子。

    首先看类 C 的 init 方法:

    super(C,self).__init__()
    

    这里的 self 是当前 C 的实例,self.class.mro() 结果是:

    [<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>]
    

    可以看到,C 的下一个类是 A,于是,跳到了 A 的 init,这时会打印出 enter A,并执行下面一行代码:

    super(A,self).__init__()
    

    注意,这里的 self 也是当前 C 的实例,MRO 列表跟上面是一样的,搜索 A 在 MRO 中的下一个类,发现是 B,于是,跳到了 B 的 init,这时会打印出 enter B,而不是 enter Base。

    整个过程还是比较清晰的,关键是要理解 super 的工作方式,而不是想当然地认为 super 调用了父类的方法。

    小结

    • 事实上,super 和父类没有实质性的关联。
    • super(cls, inst) 获得的是 cls 在 inst 的 MRO 列表中的下一个类。
    展开全文
  • Python的super函数到底做了啥

    千次阅读 2021-05-31 20:41:37
    Python的super函数到底做了啥 super相关的介绍文章有很多,而且在python中使用得也较多,尤其是在定义深度神经网络模型时,相信大家对于 super(className, self).__init__() 这一语句不会感到陌生。本篇文章主要...

    super相关的介绍文章有很多,而且在python中使用得也较多,尤其是在定义深度神经网络模型时,相信大家对于 super(className, self).__init__() 这一语句不会感到陌生。本篇文章主要记录我对super的理解,给大家以尽量简单易懂的方式进行介绍。

    一、直观的理解

    super的作用就是执行父类的方法

    以单继承为例:

    class A:
        def a(self):
            print('A')
    class B(A):
        def b(self):
            super().a()
    B().a()
    
    >>> A
    

    可以看到B().a()实质上执行的是A.a

    二、怎样辨别多继承情况

    MRO 序列:记录了各个类继承的先后顺序

    MRO 的介绍可以查看这篇文章:Python3-cookbook MRO

    只要知道 MRO 序列,无论super怎么变化都行

    class A:
        def p(self):
            print('A')
    class B():
        def p(self):
            print('B')
    class C(A,B):
        def p(self):
            print('C')
    class D(C):
        def p(self):
            print('D')
    a = A()
    b = B()
    c = C()
    d = D()
    

    四个类的MRO (可以通过查看__mro__属性获得,例如A.mro)) 分别是:
    A: (A, object)
    B: (B, object)
    C: (C, A, B, object)
    D: (D, C, A, B, object)

    以A类为例,它的MRO顺序是他自己和object,因为python里一切都是对象,所以你可以看到四个类的终点都是object。那C类的 MRO 也好理解,第一个顺序永远是自己,然后按照代码顺序依次是 A,B,最后是object。

    相信看到这你应该知道MRO是什么意思了吧,那super是怎么用的呢?

    super本身其实就是一个类,super()其实就是这个类的实例化对象,它需要接收两个参数 super(class, obj),它返回的是obj的MRO中class类的父类:

    class:就是类,这里你可以是A,B,C或者D
    obj:就是一个具体的实例对象,即a,b,c,d。我们经常在类的__init__函数里看到super的身影,而且一般都是写成这个样子:super(className, self).init(),其中self指向的是某个实例化对象本身。

    三、举例说明

    例一

    super(C, d).p()
    

    前面我们说过super的作用是:返回的是obj的MRO中class类的父类。在这里就返回的是d的MRO中C类的父类:

    返回的是d的MRO:(D, C, A, B, object)
    中C类的父类:A
    那么super(C, d)就等价于A,那么super(C, d).p()会输出A


    例二

    super(A, c).p()
    

    返回的是c的MRO中A类的父类:

    返回的是c的MRO:(C, A, B, object)
    中C类的父类:B
    所以最后的输出是B


    例三

    注意:本例有些类不含super()

    class A:
        def p(self):
            print('A')
    class B(A):
        def p(self):
    		super().p()
            print('B')
    class C(B):
        def p(self):
            print('C')
    class D(C):
        def p(self):
            print('D')
    
    d = D()
    d.p()
    

    这个很简单,最后只会输出D
     
    那如果D类改成如下样子呢?

    class D(C):
        def p(self):
    		super().p()
            print('D')
    

    我们首先写出D的MRO为 (D,C,B,A,object),缺省状态下,super()就表示前一个父类,这里就是C类,那么super().p()就会调用C的p函数,但是C.p里没有调用super,所以就与A,B类无关了,那么最终的输出就是C,D


    总结

    无论有多少个super(class, obj),我们首先确定obj的MRO是什么,然后找到class的前一个class即可。

    展开全文
  • Python 子类通过super函数调用父类

    千次阅读 2018-07-17 17:06:42
    Python中子类调用父类的方法有两种方法...2.使用super函数。super(FooChild,self).__init__(xxx,xxx) 如下例子: class A(object): def __init__(self,xing,gender): self.namea="aaa" self.xing =...

    Python中子类调用父类的方法有两种方法能够实现:

    1.直接调用父类构造方法,

    2.使用super函数。super(FooChild,self).__init__(xxx,xxx)

    如下例子:

    class A(object):
        def __init__(self,xing,gender):
            self.namea="aaa"
            self.xing = xing
            self.gender = gender
             
        def funca(self):
            print("function a : %s"%self.namea)
      
    class B(A):
        def __init__(self,xing,gender,age):
            super(B,self).__init__(xing,age)
            self.nameb="bbb"
            ##self.namea="ccc"
            self.xing = xing.upper()       
            self.age = age + 1
            #self.gender = gender.upper()
             
        def funcb(self):
            print("function b : %s"%self.nameb)
      
    b=B("lin","nan",22)
    print(b.nameb)
    print(b.namea)
    print(b.xing)
    print(b.age)
    b.funcb()
    b.funca()
    print(b.gender)   ####

       结果如下:

    bbb
    aaa
    LIN
    23
    function b : bbb
    function a : aaa
    22
    

    so

    1.B类继承A类,在B类自己的基础上可以调用A类所有的方法

    2.A、B同时拥有__init__,B会改写A中的__init__方法

    3.super函数可以调用A父类中的属性,如namea、xing,B类中有同名属性时,覆盖A类中的同名属性。

    4.super函数原理:super().__init__(xxx,xxx)中的xxx参数为类B中输入的参数,但与类A中参数名相对应。如上面那段代码中输入的是age参数,虽然运行结果并没错,但是其实这个age参数是赋值到A类的gender参数上的,如最后的b.gender

    5.使用super函数时,可将B子类中与A类相同的参数依次写入__init__(xxx)的xxx参数中(注意self参数已在super()中传入,在__init__()中将隐式传递,不需要写出,也不能写),之后可再次重写xxx中参数属性,子类多余参数可自定义属性,如class B的__init__里的参数

    展开全文
  • java 的super 函数

    千次阅读 2018-05-09 16:15:29
    要说super就先要说this。"this",作为一个特殊的关键字,它的规则如下: 1。可以表示构造函数传递。this(a,b)表示调用另外一个构造函数。这里面的this就是一个特殊语法,不是变量,没有什么类型。 2。可以...
    要说super就先要说this。
    "this",作为一个特殊的关键字,它的规则如下:
    1。可以表示构造函数传递。this(a,b)表示调用另外一个构造函数。这里面的this就是一个特殊语法,不是变量,没有什么类型。
    2。可以在一个类的非static成员内部使用,表示当前这个对象。此时,this就是一个final的普通变量,它有静态类型,就是这个类C本身;它有动态类型,就是当前这个对象的类型。你可以对它调用成员函数,把它传递给别的函数,等等等等。只要一个C类型的final变量可以出现的地方,它就可以出现。

    "super"。它和"this"类似,但是也有不同的地方。
    1。表示调用父类的构造函数。也是一个特殊语法,不是变量,没有什么类型。

    2。可以在一个类的非static成员内部使用。比如super.method()。
    但是,注意,这个super.method()只是长得跟some_var.method()一样,一个语法糖而已。实质上,"super"根本不是一个变量。

    为什么不是?因为如果是就坏了。java里面有一个金科玉律:任何public非static函数的调用都是多态的。
    所以,如果super是个变量,也指向当前对象,那么,不管super的静态类型是什么super.method()必然调用的是子类的那个版本,而不会是我们期望的,静态地选择父类的那个版本。

    所以,你只要把super.xxx看成一个特殊的语法,比如理解为“super::xxx”就好了。

    既然super不是一个变量,那么不能把它象一个普通变量那样"==",或者传递给某个函数就看起来很正常了,是么?何况,你其实也用不着它,有this你这些要求就都可以办到了。

    3。super的另外一个作用是调用父类的protected函数。只有通过"super"这个魔咒,我们才能操作父类的protected成员,别无它法。
    展开全文
  • Python super函数

    千次阅读 2014-07-08 17:27:56
    super函数提出  因此,自Python 2.2开始,Python添加了一个关键字super,来解决这个问题。下面是Python 2.3的官方文档说明:  super(type[, object-or-type])  Return the superclass of type. If the ...
  • Python3中的super函数

    千次阅读 多人点赞 2019-05-28 21:49:31
    super()是python子类继承父类的方法而使用的关键字,当子类继承父类后,就可以使用父类的方法 一,单继承(只继承一个父类,父类没有继承其他类) class A(object): def __init__(self): print('i am class A') ...
  • Java中super函数的用法

    千次阅读 2020-05-18 20:53:37
    super指代变量,用于在子类中指代父类对象。 三种用法: 访问父类的方法。 调用父类构造方法。 访问父类中的隐藏成员变量。 常用的是访问父类方法,且参数个数类型必须一致 class A{ int x,y; A(int x,int y){ ...
  • python中的super函数及MRO

    千次阅读 多人点赞 2018-08-31 18:35:07
    super() 函数是用于调用父类(超类)的一个方法。 super是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种...
  • 问题 子类如果重写了父类的方法,就会把父类的方法覆盖。...2.使用super函数,也就是我们今天要讲的重点 实例说明 举个例子,首先来看一下代码 class Fish: def _init_(self): #坐标取0到10之间的随机数 ...
  • 上面,b调用了class B,... super().__init__(name=name) # 此处直接调用父类,将构造函数交给父类去实例化,可以重用父类的代码 # 既然我们要重写B的构造函数,方法不一定是__init__方法,为什么还要去调用super? # s
  • Python3之方法的覆盖与super函数

    千次阅读 2018-09-08 23:47:50
    # 示意super函数间接调用父类中被覆盖的方法 class A: def work(self): print('A.work被调用') class B(A): '''B类继承A类''' def work(self): print('B.work被调用') def super_work(self): '''调用B类...
  • 本文给大家分享的是Python中的super函数的简单介绍以及用法和注意事项,有需要的小伙伴可以参考下
  • 如图所示: 子类对象通过super()函数调用父类的run函数,然后直接调用了子类的demo函数,而没有调用父类的函数;...从这里就说明了一切,通过super函数调用父类函数,等同于将父类中的函数copy到子类中执行;对...
  • 在 super() 被调用之前,子类是不能使用 this 的,ES6 要求,子类的构造函数必须执行一次super函数,否则 JavaScript 引擎会报错。传递 props 给 super() 的原因则是便于(在子类中)能在 constructor 访问 this.props...
  • python中的super()函数

    千次阅读 2018-06-17 10:55:04
    最能感受到super函数的作用在于进行钻石继承的时候。 钻石继承:由一个基类衍生两个及以上的超类,然后在衍生,在类树的最底层生成一个子类,这样的类树结构就是一个类似 钻石外形,所以,最底层类继承称为钻石继承...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 490,072
精华内容 196,028
关键字:

super()函数