0
点赞
收藏
分享

微信扫一扫

python super详解

言午栩 2022-04-17 阅读 83
python

super()详解

最常用的用法

from objprint import op

class Person:
    def __init__(self, name):
        self.name = name

class Male(Person):
    def __init__(self, name):
        super().__init__(name)
        self.gender = "male"

m = Male("Peter")
op(m)

输出结果

<Male 0x28cffaa1780
  .gender = 'male',
  .name = 'Peter'  
>

super本质

super是一个class,类型为type,是一个内置类的名字

super()不是调用了一个函数,而是建立了一个super的对象

super的完整版

class super(object):
    """
    super() -> same as super(__class__, <first argument>)
    super(type) -> unbound super object
    super(type, obj) -> bound super object; requires isinstance(obj, type)
    super(type, type2) -> bound super object; requires issubclass(type2, type)
    Typical use to call a cooperative superclass method:
    class C(B):
        def meth(self, arg):
            super().meth(arg)
    This works for class methods too:
    class C(B):
        @classmethod
        def cmeth(cls, arg):
            super().cmeth(arg)
    """

super的第一个参数是一个type,第二个参数是一个type或object,第二个参数决定了这个super()的点后面的函数bind到哪一个object或class上。同时,第二个参数决定了使用哪一个**MRO**,第一个参数决定在该MRO链上从哪个class往后找(不包括这个class)。

举例


from objprint import op

class Animal:
    def __init__(self, age):
        self.age = age

class Person(Animal):
    def __init__(self, age, name):
        super().__init__(age)
        self.name = name

class Male(Person):
    def __init__(self, age, name):
        super().__init__(age, name)
        self.gender = "male"

m = Male(34, "Peter")
op(m)

输出

<Male 0x146794f82b0
  .age = 34,
  .gender = 'male',
  .name = 'Peter'
>

from objprint import op

class Animal:
    def __init__(self, age):
        self.age = age

class Person(Animal):
    def __init__(self, age, name):
        super().__init__(age)
        self.name = name

class Male(Person):
    def __init__(self, age, name):
        super(Person, self).__init__(age, name)
        self.gender = "male"

m = Male(34, "Peter")
op(m)

输出

TypeError: Animal.__init__() takes 2 positional arguments but 3 were given

当前的MRO链为:Male->Person->Animal->Object

所以会调用Person类的父类——Animal类的__init__函数

另一种用法

from objprint import op

class Animal:
    def __init__(self, age):
        self.age = age

class Person(Animal):
    def __init__(self, age, name):
        super().__init__(age)
        self.name = name

class Male(Person):
    def __init__(self, age, name):
        super(Person, self).__init__(age)
        self.gender = "male"

m = Male(34, "Peter")
super(Male, m).__init__(12,"pepper")
op(m)

结果

<Male 0x2762c13fe20
  .age = 12,
  .gender = 'male',
  .name = 'pepper'
>

只传一个参数给super

只传给super一个object的时候,它会变成一个unbound的对象,需要把它bind到别的object上才可以使用

助于深入理解的例子

class A:
    def say(self):
        print("A")


class B(A):
    def say(self):
        super().say()


class C(A):
    def say(self):
        print("C")


class M(B, C):
    def say(self):
        B.say(self)


m = M()
m.say()

打印结果是:C

为什么?在调用say()方法的时候,用的self是M的self,即当前的MRO链是M的MRO链:M->B->C->A,寻找方法的顺序是由self的MRO决定的,所以最先在C里找到say()方法

参考视频

https://www.bilibili.com/video/BV1FL4y1E7xK

举报

相关推荐

0 条评论