Method Resolution Order (MRO) in new-style classes?

后端 未结 4 715
离开以前
离开以前 2020-11-22 10:00

In the book Python in a Nutshell (2nd Edition) there is an example which uses
old style classes to demonstrate how methods are resolved in classic resolution or

4条回答
  •  借酒劲吻你
    2020-11-22 10:31

    The crucial difference between resolution order for legacy vs new-style classes comes when the same ancestor class occurs more than once in the "naive", depth-first approach -- e.g., consider a "diamond inheritance" case:

    >>> class A: x = 'a'
    ... 
    >>> class B(A): pass
    ... 
    >>> class C(A): x = 'c'
    ... 
    >>> class D(B, C): pass
    ... 
    >>> D.x
    'a'
    

    here, legacy-style, the resolution order is D - B - A - C - A : so when looking up D.x, A is the first base in resolution order to solve it, thereby hiding the definition in C. While:

    >>> class A(object): x = 'a'
    ... 
    >>> class B(A): pass
    ... 
    >>> class C(A): x = 'c'
    ... 
    >>> class D(B, C): pass
    ... 
    >>> D.x
    'c'
    >>> 
    

    here, new-style, the order is:

    >>> D.__mro__
    (, , , 
        , )
    

    with A forced to come in resolution order only once and after all of its subclasses, so that overrides (i.e., C's override of member x) actually work sensibly.

    It's one of the reasons that old-style classes should be avoided: multiple inheritance with "diamond-like" patterns just doesn't work sensibly with them, while it does with new-style.

提交回复
热议问题