简体   繁体   English

试图了解 Python MRO,但对其解析顺序感到困惑

[英]Trying to understand Python MRO, but confused with its resolution order

So I was trying to understand how the MRO works and I unable to understand some parts of it, I understand that the interpreter goes left to right and chooses specificity over generics, if so then how does this happen?所以我试图了解 MRO 是如何工作的,但我无法理解其中的某些部分,我知道解释器从左到右并选择 generics 的特异性,如果是这样,那么这是怎么发生的?

class X:
    pass

class Y:
    pass

class Z:
    pass

class w:
    pass

class A(X, Y):
    pass

class B(w, Z):
    pass

class D(X, w):
    pass

class M(D, A, B, Z):
    pass


print(M.mro())

# Output
# [<class '__main__.M'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.X'>,
#  <class '__main__.Y'>, <class '__main__.B'>, <class '__main__.w'>, <class '__main__.Z'>, 
# <class 'object'>]

or this或这个

class X:
    pass


class Y:
    pass


class Z:
    pass


class A(X, Y):
    pass


class B(Y, Z):
    pass


class M(B, A, Z):
    pass

# Output:
# [<class '__main__.M'>, <class '__main__.B'>,
#  <class '__main__.A'>, <class '__main__.X'>,
#  <class '__main__.Y'>, <class '__main__.Z'>,
#  <class 'object'>]

print(M.mro())

Could someone help me understand the resolution order, because to me it feels like the rules are contradicting each other, each time the inheritance level get a bit more complex.有人可以帮我理解解决顺序,因为对我来说,每次 inheritance 级别变得更复杂时,我感觉规则是相互矛盾的。

The MRO follows from two simple rules: MRO 遵循两个简单的规则:

  1. Every class precedes its ancestor(s) in the MRO.每个 class 在 MRO 中都位于其祖先之前。
  2. If a class has more than one parent, the parents appear in-order (but not necessarily consecutively) in the MRO.如果 class 有多个父级,则父级在 MRO 中按顺序(但不一定连续)出现。

Consider M .考虑M By rule 1, M must occur before B , A , and Z .根据规则 1, M必须出现在BAZ之前。 By rule 2, B must come before A , and A must come before Z .根据规则 2, B必须在A之前,并且A必须在Z之前。

Note that it isn't always possible to find an MRO that obeys these rules, in which case you'll get an error immediately:请注意,并非总是可以找到遵守这些规则的 MRO,在这种情况下,您会立即收到错误消息:

>>> class X: pass
...
>>> class Y: pass
...
>>> class A(X, Y): pass
...
>>> class B(Y, X): pass
...
>>> class C(A, B): pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Cannot create a consistent method resolution
order (MRO) for bases X, Y

A and B are fine, but no MRO can be found for C . AB都很好,但找不到C的 MRO。 In C 's MRO, X would have to precede Y since C inherits from A .C的 MRO 中, X必须在Y之前,因为C继承自A But because C also inherits from B , Y must precede X .但是因为C也继承自B ,所以Y必须在X之前。 There's no ordering that satisfies both constraints.没有满足这两个约束的排序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM