前两天被多继承坑了下,今天写个记录
class B():
def fun(self):
print('B')
class C():
def fun(self):
print('C')
class D(B,C):
def fun(self):
super(D,self).fun()
print('D')
if __name__ == '__main__':
print(D.__mro__)
d=D()
d.fun()
这里我们尝试D继承BC并调用BC的方法
然而结果和我们想的却不一样,D确实继承了BC,但是为什么C的方法没有调用?
原因在于同名的方法被B覆盖掉了,我们要怎么修改才能让BC的方法都生效呢?
在其他语言中比如C++就有虚基类来解决这种二义性的问题,这里python有个类似的方法
class A():
def fun(self):
pass
class B(A):
def fun(self):
super(B,self).fun()
print('B')
class C(A):
def fun(self):
super(C,self).fun()
print('C')
class D(B,C):
def fun(self):
super(D,self).fun()
print('D')
if __name__ == '__main__':
print(D.__mro__)
d=D()
d.fun()
我们来看结果
这里我们通过BC继承自同一个父类A的方法解决了二义性的问题(至于原理以后有时间再写)
但是这里我们注意到了另一个问题,为什么C在B的上面?这个顺序是怎么得到的?这里有涉及到了MRO
python使用c3算法处理继承顺序问题,这里我的理解其实就是拓扑排序
python按照继承括号内的顺序通过拓扑排序依次把类从图中取下,
按拓扑排序先取D,然后B,C入度为0可以去下,取下顺序按照括号内继承顺序来,先B后C,最后是A
也就是D-B-C-A
感觉这部分还是没解释清楚,等哪天彻底搞懂了再重新写吧
class A():
def fun(self):
print ('A')
class B(A):
def fun(self):
print('B1')
super(B,self).fun()
print('B2')
class C(A):
def fun(self):
print('C1')
super(C,self).fun()
print('C2')
class D(B,C):
def fun(self):
print('D1')
super(D,self).fun()
print('D2')
if __name__ == '__main__':
print(D.__mro__)
d=D()
d.fun()