admin 管理员组文章数量: 887021
2024年1月17日发(作者:csdn官网c认证)
概述
super() 是python 中调用父类(超类)的一种方法,在子类中可以通过super()方法来调用父类的方法。【超类: 是指 2层以上的继承关系,假如 C类继承B类,B类由继承A类,那么A类就是C类的超类】
作用:
在继承中,让代码维护更加简单
解决多继承带来的重复调用(菱形继承)、查找顺序(MRO)问题
语法:
super(type[, object-or-type])
参数:
type – 类。
object-or-type – 类,一般是 self
Python 3 和 Python 2 的另一个区别是: Python 3 可以使用直接使用
super().xxx 代替 super(Class, self).xxx :
super的使用
1.通过super() 来调用父类的__init__ 构造方法:
class Person():
def __init__(self):
print('我是Peson的__init__构造方法')
class Student(Person):
def __init__(self):
super().__init__()
print('我是Student的__init__构造方法')
stu = Student()
-----------------------------------------
我是Peson的__init__构造方法
我是Student的__init__构造方法
2 通过supper() 来调用与子类同名的父类方法
2.1 单继承
在单继承中 super 就像大家所想的那样,主要是用来调用父类的方法的。
class A:
def __init__(self):
self.n = 2
def add(self, m):
print('self is {0} @'.format(self))
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
print('self is {0} @'.format(self))
super().add(m)
self.n += 3
b = B()
(2)
print(b.n)
我们执行以上代码,得到的输出如下:
self is <__main__.B object at 0x106c49b38> @
self is <__main__.B object at 0x106c49b38> @
这个结果说明了两个问题:
1、super().add(m) 确实调用了父类 A 的 add 方法。
2、super().add(m) 调用父类方法 def add(self, m) 时, 此时父类中 self 并不是父类的实例而是子类的实例, 所以 (2) 之后的结果是 5 而不是 4 。
补充说明:
MRO—方法搜索顺序
MRO是method resolution order,主要用于在对继承是判断方法、属性的调用路径【顺序】,其实也就是继承父类方法时的顺序表。
Python中针对类提供了一个内置属性__mro__可以查看方法的搜索顺序
class C(A,B):
pass
print(C.__mro__)
out:
(
在搜索方法时,是按照__mro__的输出结果从左到右的顺序查找的
如果当前类中找到方法,就直接执行,不再搜索
如果没有找到,就查找下一个类中是否有对应的方法,如果找到,就直接执行,不再搜索
如果找到最后一个类,还是没有找到方法,程序报错
2.2 多继承
在多继承中,会涉及到一个MRO(继承父类方法时的顺序表) 的调用排序问题。即严格按照MRO 顺序执行super方法
class A:
def __init__(self):
self.n = 2
def add(self, m):
print('self is {0} @'.format(self))
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
print('self is {0} @'.format(self))
super().add(m)
self.n += 3
class C(A):
def __init__(self):
self.n = 4
def add(self, m):
print('self is {0} @'.format(self))
super().add(m)
self.n += 4
class D(B, C):
def __init__(self):
self.n = 5
def add(self, m):
print('self is {0} @'.format(self))
super().add(m)
self.n += 5
d = D()
(2)
print(d.n)
out:
self is <__main__.D object at 0x10ce10e48> @
self is <__main__.D object at 0x10ce10e48> @
self is <__main__.D object at 0x10ce10e48> @
self is <__main__.D object at 0x10ce10e48> @
同样,不管往上调用几次,调用父类方法中 self 并不是父类的实例而是子类的实例,在上例中都是D的实例化对象
() == [D,B, C, A, object] ,多继承的执行顺序会严格按照mro的顺序执行。
整体的调用流程图如下:
d = D()
d.n == 5
(2)
class D(B, C): class B(A): class C(A): class A:
def add(self, m): def add(self, m): def add(self, m): def
add(self, m):
super().add(m) 1.---> super().add(m) 2.---> super().add(m) 3.---> self.n += m
self.n += 5 <------6. self.n += 3 <----5. self.n += 4 <----4.
<--|
(14+5=19) (11+3=14) (7+4=11)
(5+2=7)
其它:
().__init__相对于类名.init,在单继承上用法基本无差别
2.但在多继承上有区别,super方法能保证每个父类的方法只会执行一次,而使用类名的方法会导致方法被执行多次。
3.多继承时,使用super方法,对父类的传参数,应该是由于python中super的算法导致的原因,必须把参数全部传递,否则会报错
4.单继承时,使用super方法,则不能全部传递,只能传父类方法所需的参数,否则会报错。
版权声明:本文标题:python中super的用法 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/free/1705423022h484171.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论