本篇内容介绍了“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__)
以上执行结果为
这个结果也符合理解,
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')
执行结果同上
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__)
执行结果为
可以看到 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)
执行结果为
可以看到
Male实例化的时候绕过了
Person,只输出了
Animal和
Male。而在类之外执行的
super,执行了
Male的父类(Person、Animal)的
__init__方法。 说明了 2 点:
super
的第一个参数决定了选择self
的 mro 哪个 class 之后的 class。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()获取