3 回答
TA贡献1829条经验 获得超6个赞
Python的方法解析顺序实际上比仅仅理解钻石模式更复杂。到真的理解它,看看C3线性化..我发现在扩展方法以跟踪订单时使用print语句确实有帮助。例如,您认为这种模式的输出是什么?(注意:“X”应该是两个交叉边,而不是一个节点,^表示调用Super()的方法。)
class G(): def m(self): print("G")class F(G): def m(self): print("F") super().m()class E(G): def m(self): print("E") super().m()class D(G): def m(self): print("D") super().m()class C(E): def m(self): print("C") super().m()class B(D, E, F): def m(self): print("B") super().m()class A(B, C): def m(self): print("A") super().m()# A^# / \# B^ C^# /| X# D^ E^ F^# \ | /# G
你拿到B、D、C、E、F、G了吗?
x = A()x.m()
经过多次尝试,我对C3线性化提出了一个非正式的图论解释:(如果这是错误的,请告诉我。)
考虑这个例子:
class I(G):
def m(self):
print("I")
super().m()
class H():
def m(self):
print("H")
class G(H):
def m(self):
print("G")
super().m()
class F(H):
def m(self):
print("F")
super().m()
class E(H):
def m(self):
print("E")
super().m()
class D(F):
def m(self):
print("D")
super().m()
class C(E, F, G):
def m(self):
print("C")
super().m()
class B():
def m(self):
print("B")
super().m()
class A(B, C, D):
def m(self):
print("A")
super().m()
# Algorithm:
# 1. Build an inheritance graph such that the children point at the parents (you'll have to imagine the arrows are there) and
# keeping the correct left to right order. (I've marked methods that call super with ^)
# A^
# / | \
# / | \
# B^ C^ D^ I^
# / | \ / /
# / | X /
# / |/ \ /
# E^ F^ G^
# \ | /
# \ | /
# H
# (In this example, A is a child of B, so imagine an edge going FROM A TO B)
# 2. Remove all classes that aren't eventually inherited by A
# A^
# / | \
# / | \
# B^ C^ D^
# / | \ /
# / | X
# / |/ \
# E^ F^ G^
# \ | /
# \ | /
# H
# 3. For each level of the graph from bottom to top
# For each node in the level from right to left
# Remove all of the edges coming into the node except for the right-most one
# Remove all of the edges going out of the node except for the left-most one
# Level {H}
#
# A^
# / | \
# / | \
# B^ C^ D^
# / | \ /
# / | X
# / |/ \
# E^ F^ G^
# |
# |
# H
# Level {G F E}
#
# A^
# / | \
# / | \
# B^ C^ D^
# | \ /
# | X
# | | \
# E^F^ G^
# |
# |
# H
# Level {D C B}
#
# A^
# /| \
# / | \
# B^ C^ D^
# | |
# | |
# | |
# E^ F^ G^
# |
# |
# H
# Level {A}
#
# A^
# |
# |
# B^ C^ D^
# | |
# | |
# | |
# E^ F^ G^
# |
# |
# H
# The resolution order can now be determined by reading from top to bottom, left to right. A B C E D F G H
x = A()
x.m()
TA贡献1811条经验 获得超6个赞
你得到的结果是正确的。尝试更改Base3
到Base1
并与经典类的相同层次结构进行比较:
class Base1(object): def amethod(self): print "Base1"class Base2(Base1): passclass Base3(Base1): def amethod(self): print "Base3"class Derived(Base2,Base3): passinstance = Derived()instance.amethod()class Base1: def amethod(self): print "Base1"class Base2(Base1): passclass Base3(Base1): def amethod(self): print "Base3"class Derived(Base2,Base3): passinstance = Derived()instance.amethod()
现在它的产出是:
Base3Base1
添加回答
举报