Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does super try each class in MRO

class Base(object):
    def m(self):
        print 'base'


class MixinA(Base):
    def m(self):
        super(MixinA, self).m()
        print 'mixin a'


class MixinB(Base):
    def m(self):
        super(MixinB, self).m()
        print 'mixin b'


class Top(MixinB, MixinA, Base):
    def m(self):
        super(Top, self).m()
        print 'top'


t = Top()
t.m()

This prints:

base
mixin a
mixin b
top

I'm surprised by multiple things. First MRO of Top is (<class 'Top'>, <class 'MixinB'>, <class 'MixinA'>, <class 'Base'>, <type 'object'>)

  1. Why mixin a comes before mixin b?
  2. Does super try every class in MRO (unlike searching for an attribute when the first attribute found is returned)?
like image 896
Mariy Avatar asked Mar 25 '26 11:03

Mariy


1 Answers

No, super() does not 'try' each class in the MRO. Your code chains the calls, because each method called has another super() call in it. Top.m() calls super().m(), which resolves to MixinB.m(); which in turn uses super() again, etc.

mixin a is printed before mixin b because you are printing after the super() call, so the last element in the MRO is executed first. The super() call is just another method call, so a print statement after such a call won't be executed until the super().m() call has completed.

Your MRO is as follows:

>>> type(t).__mro__
(<class '__main__.Top'>, <class '__main__.MixinB'>, <class '__main__.MixinA'>, <class '__main__.Base'>, <type 'object'>)

so naturally Base.m() is called last and gets to print first, followed by MixinA, then MixinB, and Top being the last to print.

Note that the MRO of self is used, not of the class you pass into super() as the first argument; the MRO is thus stable throughout all calls in your hierarchy for any given instance.

If you expected the print statements to be executed in the order the MRO calls are chained, you'll have to put the print statements before calling the next m() method in the MRO.

like image 111
Martijn Pieters Avatar answered Mar 27 '26 18:03

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!