与大多数语言相同,Python
支持多继承,其声明方式也很简单:class Child(Parent1, Parent2, Parent3...)
提到多继承,就必须要说一下经典的菱形继承关系。如下图

代码部分如下:
class A(object):
def getvalue(self):
print 'getvalue from A'
def show(self):
print 'show from A'
class B(A):
def getvalue(self):
print 'getvalue from B'
class C(A):
def getvalue(self):
print 'getvalue from C'
def show(self):
print 'show from C'
class D(B, C):
pass
d = D()
d.getvalue()
d.show()
上面这段代码的执行结果是getvalue from B
和show from C
。
这就牵扯到Python
中多继承时,MRO(Method Resolution Order 方法解析顺序)的实现了。
Python
中的MRO大概是下面的策略:
- 由c1,c2...cn表示类c1至cn的序列,而对于c的继承顺序是b1,b2...bn,L[c]表示c的线性继承关系,L[object]=object。
- 具体实现是:L[C(b1b2...bn)] = c + merge(L[b1],L[b2]...L[bn], b1...bn)
3.其中merge的计算是:在L[b1]L[bn],b1...bn中,取L[b1]所继承的第一个基类,若果这个类不在L[b2]...L[bn],b1...bn的序列中,则把这个类加入到线性继承序列中,同时将其出队。
结合上面的代码实例,可以得到下面的计算过程(O是object的简写):
L[O] = O
L[A]=A, O
L[B] = B + merge(L[A])
= B + merge(A, O)
= B + A + merge(O, O)
= B, A, O
L[C] = C + merge(L[A])
= C + merge(A, O)
= C + A + merge(O, O)
= C, A, O
L[D] = D + merge(L[B], L[C], BC)
= D + merge(BAO, CAO, BC)
= D + B + merge(AO, CAO, C)
= D + B + C + merge(AO, AO)
= D+B+C+A+O
= D, B, C, A, O
所以,在D的实例d中执行方法是,寻找的顺序使D->B->C->A->O,这个顺序可以通过print d.__mro__
直接验证。
相同的,不仅是类方法,类属性的查找顺序也遵循MRO。
简单来说,菱形继承是一种多继承的情景,但它的MRO有时候可能并不是我们所期待的样子。所以,在实际代码中要尽可能去避免菱形继承的情景出现。
网友评论