python中的super如何使用

2023-06-12 16:41:05 python super 如何使用

本篇内容介绍了“python中的super如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

super 的完整形式

常见的

super
用法如下

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

class Male(Person):
    def __init__(self,age):
        super().__init__('xiaoming')
        self.age = age
        print("Male")

m = Male(12)
print(m.__dict__)

以上执行结果为

python中的super如何使用

这个结果也符合理解,

Male
继承了
Person
,在初始化的时候执行了父类的初始化方法,也就继承了父类的 name 属性。

但是其实

super
的完整形式为

super(Male, self).__init__('xiaoming')

super
是一个,其中第二个参数是个 class 或者 object,决定了使用怎样的 mro。第一个参数是个 class,决定了从 mro 哪个 class 后面的 class 开始寻找,并将函数绑定到第二个参数上。两个参数都是可选的。

本例中,

self
就是
Male
的实例对象,于是
self
的 mro 就是 [
Male
,
Person
,
Object
],而第一个参数是
Male
,于是就使用
Male
后面的
Person
,发现
Person
__init__
函数,于是就只执行
Person
__init__
函数,也就是
super
行的语句等价于

# super(Male, self).__init__('xiaoming')
Person.__init__(self,'xiaoming')

执行结果同上

python中的super如何使用

super 的使用

super
可以在定义类之外的地方使用

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

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

class Male(Person):
    def __init__(self,name,age):
        super(Person,self).__init__(name,age)
        print("Male")

m = Male('xiaoming',12)
super(Male,m).__init__('xiaoming',12)
print(m.__dict__)

执行结果为

python中的super如何使用

可以看到 16 行报错了,报错的原因就是此时的

self
代表的是
Male
实例,
Male
的 mro 是
Male
Person
Animal
Object
Male
在实例化的时候执行了父类的
__init__
方法,而此时
super
的第一个参数是
Person
,于是使用
Person
后面的
Animal
,而
Animal
__init__
方法只有一个参数,
super
却传递了2个参数,于是报错了。正确地修改为

# class Person:
super(Person,self).__init__(name)

执行结果为

python中的super如何使用

可以看到

Male
实例化的时候绕过了
Person
,只输出了
Animal
Male
。而在类之外执行的
super
,执行了
Male
的父类(Person、Animal)的
__init__
方法。 说明了 2 点:

  1. super
    的第一个参数决定了选择
    self
    的 mro 哪个 class 之后的 class。

  2. super
    可以在类定义之外执行。

再看一个例子将会更加明白

python中的super如何使用

直觉上来说,

D
的实例会执行父类的
say()
,首先会找到
B
,于是会执行
B
的父类的
say()
,于是会输出
'A'
。结果却是
'C'
,原因就是
self
代表了
D
的实例,而
D
的 mro 是
['B','C','A']
D
的实例执行父类的
say()
,会找到
B
执行
B
super
方法,相当于
super(B,self).say()
,而此时的
self
代表
D
,mro 搜索会选择
B
后面的 class 也就是
C
,执行
C
say()
,于是最终结果输出
'C'

类中使用

super
的时候,可以省略参数而直接写成
super()
这时 super 会将他所在的类当作第一个参数,将所在函数的第一个参数当作自己的第二个参数。显然,这样省略参数的
super
不能在类之外直接使用。

最后,查看一个类的 mro 可以用

class.__mro__
或者
class.mro()
获取

python中的super如何使用

相关文章