新类型类中的方法解析顺序(MRO)?

新类型类中的方法解析顺序(MRO)?

在书中简略的Python(第2版)有一个例子
旧的样式类来演示如何按照经典的解析顺序和
与新秩序有何不同?

通过用新样式重写示例,我尝试了同一个示例,但结果与用旧样式类获得的结果没有什么不同。我在运行示例时使用的python版本是2.5.2.下面是一个例子:

class Base1(object):  
    def amethod(self): print "Base1"  class Base2(Base1):  
    passclass Base3(object):  
    def amethod(self): print "Base3"class Derived(Base2,Base3):  
    passinstance = Derived()  instance.amethod()  print Derived.__mro__

打电话instance.amethod()版画Base1,但根据我对具有新类型类的MRO的理解,输出应该是Base3..打电话Derived.__mro__指纹:

(<class '__main__.Derived'>, <class '__main__.Base2'>, <class '__main__.Base1'>, <class '__main__.Base3'>, <type 'object'>)

我不确定我对MRO的理解是错误的,还是我做了一个我无法察觉的愚蠢的错误。请帮助我更好地理解MRO。


RISEBY
浏览 443回答 3
3回答

肥皂起泡泡

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 Hx = A()x.m()

杨魅力

你得到的结果是正确的。尝试更改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
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python