1

With the code below

class A(object):
    def TestMRO(self):
        s = super()
        print(f'A: s = {s}')
        return super().TestMRO()

class B(object):
    def TestMRO(self):
        print('B')
        return 1

class C(object):
    def TestMRO(self):  # abstract
        print('C')
        raise NotImplementedError


class D(A, B, C):
    pass


class E(D):
    pass


e = E()

e.TestMRO()

, it returns:

A: s = <super: <class 'A'>, <E object>>
B

I'm confused, why super() from class A triggered a method in class B?

wjandrea
  • 28,235
  • 9
  • 60
  • 81
athos
  • 6,120
  • 5
  • 51
  • 95
  • 1
    It's called MRO (method resolution order). In this case the method resolution order is E → D → A → B→ C. So from A, super() is B. – mkrieger1 Mar 08 '22 at 19:11
  • 2
    "I'm confused, why super() from class A triggered a method in class B?" - why do you think it should *not*? – mkrieger1 Mar 08 '22 at 19:13
  • Because that's the order in ``D(A, B, C)``... Where else should it point to? – MisterMiyagi Mar 08 '22 at 19:17
  • 3
    `A` does not inherit from `B`, so I can understand questioner's confusion. – John Gordon Mar 08 '22 at 19:19
  • 1
    Python uses [C3 linearization](https://en.wikipedia.org/wiki/C3_linearization) to yield a deterministic MRO. Unfortunately, most people think of super() as a mechanism to call a method in an ancestor class (in single inheritance), not a sibling class (in multiple inheritance). – jarmod Mar 08 '22 at 19:29
  • 1
    `super` is a pretty poor name for this (but I'm not sure what would be better). – chepner Mar 08 '22 at 19:35

0 Answers0