super的用法2
约定
在开始之前我们来约定一下本文所使用的 Python 版本。默认用的是 Python 3,也就是说:本文所定义的类都是新式类。如果你用到是 Python 2 的话,记得继承 object:
# 默认, Python 3
class A:
pass
# Python 2
class A(object):
pass
Python 3 和 Python 2 的另一个区别是: Python 3 可以使用直接使用 super().xxx 代替 super(class, self).xxx :
# 默认,Python 3
class B(A):
def add(self, x):
super().add(x)
# Python 2
class B(A):
def add(self, x):
super(B, self).add(x)
所以,你如果用的是 Python 2 的话,记得将本文的 super() 替换为 suepr(class, self) 。
如果还有其他不兼容 Python 2 的情况,我会在文中注明的。
单继承
在单继承中 super 就像大家所想的那样,主要是用来调用父类的方法的。
class A:
def __init__(self):
self.n = 2
def add(self, m):
print('在A的add中self的值是{0}'.format(self))
print("A中的m是",m)#输出10
print("此时A中的n是",self.n)#注意这里输出的是3,而不是2
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
print('在B的add中self的值是{0}'.format(self))
print("B中的m是",m)#输出10
super().add(m)#调用父类的add()
print("此时B中的n是",self.n)#输出13
self.n += 5
if __name__ == '__main__':
b = B()
b.add(10)
print(b.n)#b是B实例化后的对象,n是的一个属性
执行结果如下:
在B的add中self的值是<__main__.B object at 0x0000020BE0875D30>
B中的m是 10
在A的add中self的值是<__main__.B object at 0x0000020BE0875D30>
A中的m是 10
此时A中的n是 3
此时B中的n是 13
18
这个结果说明了两个问题:
1、super().add(m) 确实调用了父类 A 的 add 方法。
2、super().add(m) 调用父类方法 def add(self, m) 时, 此时父类中 self 并不是父类的实例而是子类的实例, 所以此时A中的self.n的值也是B类中的n,即self.n得值为3而不是2 。
多继承
这次我们再定义一个 class C,一个 class D:
class A:
def __init__(self):
self.n = 2
def add(self, m):
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
super().add(m)#调用父类的add()
self.n += 5
class C(A):
def __init__(self):
self.n = 100
def add(self, m):
super().add(m)
self.n += 4
# 继承B和C类
class D(B, C):
def __init__(self):
self.n = 200
def add(self, m):
super().add(m)#调用父类的add(),即B类和C类的add()方法
self.n += 5
if __name__ == '__main__':
d = D()
d.add(10)
print(d.n)