本文转自:http://kaiyuan.me/2016/04/27/C3_linearization/

作者:Kaiyuan

注意:本文仅仅作为个人mark,所以排版并不如原文,另本文在原文基础上做了一些修改,但由于本人技术实力尚浅,所作修改可能会误导读者,建议到原文查看。

在介绍算法之前,我们首先约定需要使用的符号。我们用 C1 C2⋯CN 表示包含 N 个类的列表,并令

head(C1 C2⋯CN)=C1

tail(C1 C2⋯CN)=C2 C3⋯CN

为了方便做列表连接操作,我们记:

C1+(C2 C3⋯CN)=C1 C2⋯CN

假设类 C 继承自父类 B1,⋯,BN那么根据 C3 线性化,类 C 的方法解析列表通过如下公式确定:

L[C(B1⋯BN)]=C+merge(L[B1],⋯,L[BN],B1⋯BN)

这个公式表明 C 的解析列表是通过对其所有父类的解析列表及其父类一起做 merge 操作所得到。

接下来我们介绍 C3 线性化中最重要的操作 merge,该操作可以分为以下几个步骤:

  1. 选取 merge中的第一个列表记为当前列表 K。
  2. 令 h=head(K),如果 h 没有出现在其他任何列表的 tail 当中,那么将其加入到类 C 的线性化列表中,并将其从 merge 中所有列表中移除,之后重复步骤 1和2。
  3. 否则,设置 K 为 merge 中的下一个列表,并重复 2 中的操作。
  4. 如果 merge中所有的类都被移除,则输出类创建成功;如果不能找到下一个 h,则输出拒绝创建类 C 并抛出异常。

上面的过程看起来好像很复杂,我们用一个例子来具体执行一下,你就会觉得其实还是挺简单的。假设我们有如下的一个类继承关系:

class A(object):

    def __init__(self):
print("enter A")
super(A, self).__init__()
print("leave A") class B(object): def __init__(self):
print("enter B")
super(B, self).__init__()
print("leave B") class C(object): def __init__(self):
print("enter C")
super(C, self).__init__()
print("leave C") class D(A): def __init__(self):
print("enter D")
super(D, self).__init__()
print("leave D") class E(A, C): def __init__(self):
print("enter E")
super(E, self).__init__()
print("leave E") class F(D, B): def __init__(self):
print("enter F")
super(F, self).__init__()
print("leave F") class G(E, F): def __init__(self):
print("enter G")
super(G, self).__init__()
print("leave G") """
l[F(D, B)] = F + merge(l(D), l(B), DB)
F + merge([D, A], B, [D, B])
[F, D, A, B]
l[G(E, F)] = G + merge(l(E), l(F), EF)
G + merge([E, A, C], [F, D, A, B], [E, F])
[G, E, F, D, A, C, B] """ print(G.mro())
05-14 05:19