为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

RISEBY 2019-07-15 10:41:43
新类型类中的方法解析顺序(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。
查看完整描述

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()


查看完整回答
反对 回复 2019-07-15
?
杨魅力

TA贡献1811条经验 获得超6个赞

你得到的结果是正确的。尝试更改Base3Base1并与经典类的相同层次结构进行比较:

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


查看完整回答
反对 回复 2019-07-15
  • 3 回答
  • 0 关注
  • 442 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信