简体   繁体   中英

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?

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.

The MRO follows from two simple rules:

  1. Every class precedes its ancestor(s) in the MRO.
  2. If a class has more than one parent, the parents appear in-order (but not necessarily consecutively) in the MRO.

Consider M . By rule 1, M must occur before B , A , and Z . By rule 2, B must come before A , and A must come before 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:

>>> 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 . In C 's MRO, X would have to precede Y since C inherits from A . But because C also inherits from B , Y must precede X . There's no ordering that satisfies both constraints.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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