关键性问题是:继承顺序
在多继承的知识点中,其核心问题就是:子类继承父类的继承顺序
1. 简单的多继承
如下代码示例,C类和D类均继承A、B类(继承顺序不同)
class A:
def func(self):
print('in A')
class B:
def func(self):
print('in B')
class C(A,B):
pass
class D(B,A):
pass
obj01 = A()
obj02 = D()
obj01.func() # in A
obj02.func() # in B
由上述结果我们可以得出以下结论:
在简单的多继承中,字类继承父类的顺序适合其括号里写的顺序有关的,从左到右的顺序依次继承
2. 钻石继承
在钻石继承中,继承顺序遵循:广度优先原则
如下图,即描述了一个D类 class D(B,C)
的继承顺序
当B、C类中均由func方法时,根据class D(B,C)
描述的继承顺序,优先继承B类
class A():
def func(self):
print('in A')
class B(A):
def func(self):
print('in B')
class C(A):
def func(self):
print('in C')
class D(B,C):
pass
obj = D()
obj.func() # in B
当B类中没有func方法时,D优先继承C类,然后才是A类
class A():
def func(self):
print('in A')
class B(A):
# def func(self):
# print('in B')
pass
class C(A):
def func(self):
print('in C')
class D(B,C):
pass
obj = D()
obj.func() # in C
3. 复杂钻石继承(乌龟继承)
如下,在较为复杂的钻石继承中,类的继承顺序是遵循 C3算法
的,具体的继承顺序可以通过 mro方法
来获取
在上述继承关系的情况下,继承顺序如上数字所示,因为上述继承顺序目前从算法角度上看是最优的,类似网络中的最小路径优先
# D类没有func的情况下,会先去找B
class A():
def func(self):
print('in A')
class B(A):
def func(self):
print('in B')
class C(A):
def func(self):
print('in C')
class D(B):
# def func(self):
# print('in D')
pass
class E(C):
def func(self):
print('in E')
class F(D,E):
pass
obj = F()
obj.func() # in B
print(F.mro()) # [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
总结:
1)可通过mro方法
来获取多继承中的类的继承顺序
2)类的继承顺序遵循C3算法
4. 交叉继承
在上述的“乌龟”样式的继承上,如果继承顺序再复杂一点,可以出现交叉继承的情况,同样也是遵循C3算法
的,因此也可以通过mro方法
来获取类的继承顺序