How does `super` interacts with a class's `__mro__` attribute in multiple inheritance?

后端 未结 2 379
北恋
北恋 2021-01-19 18:43

Today, I read the official doc of super.
In which it mentioned multiple inheritance will be decided by the __mro__ attribute of a class.
So I did a bit

相关标签:
2条回答
  • 2021-01-19 19:02

    Look at the __mro__ of Son:

    __main__.Son, __main__.Father, __main__.GrandFather, __main__.Mother, object
    

    According to the doc:

    The __mro__ attribute of the type lists the method resolution search order

    So methods will be searched according to the order in the __mro__ list, from left to right. Call of super(type, instance) will change the starting position to the type specified as the first argument of super() in the __mro__ list of the class of the instance specified as the second argument (if the second argument passed to super is a instance):

    super(Son, s) will proxy to __main__.Father

    super(Father, s) will proxy to __main__.GrandFather

    super(GrandFather, s) will proxy to __main__.Mother

    super(Mother, s) will proxy to object

    The interesting part is why __mro__ of Son is like it is. In other words why Mother is after GrandFather. This is because of how the linearization is working in python:

    the linearization of C is the sum of C plus the merge of the linearizations of the parents and the list of the parents.

    See the examples in the documentation you mentioned, it explains a very similar case.

    So that final result is actually correct: super(GrandFather, s).p() should be I'm female.

    0 讨论(0)
  • 2021-01-19 19:09

    From chapt 32 of learning python:

    each super call selects the method from a next class following it in the MRO ordering of the class of the self subject of a method call.

    so for super(cls, instance)(isinstance(instance, cls) must be True), the method is selected from the next class in instance.__class__.__mro__ starting from instance.__class__.

    for super(cls0, cls1)(issubclass(cls1, cls0) must be True), the method is selected from next class in cls1.__mro__ starting from cls0

    in both cases, if the method is not implemented by the next class in the MRO chain, the search will skip ahead until it finds a class with the method defined.

    0 讨论(0)
提交回复
热议问题