0
votes

I am new to multiple and multilevel inheritance. I was trying to execute an example:

class First(object):
    def __init__(self):
        super().__init__()
        print("first")

class Second(object):
    def __init__(self):
        super().__init__()
        print("second")

class Third(First, Second):
    def __init__(self):
        super().__init__()
        print("third")
Third()

The output I got is:

second
first
third
<__main__.Third at 0x21bbaf2fc88>

Could anyone please explain me the reason for this output? I was expecting the output to be:

first
second
third

As __init__() of third would call __init__() of First class (because it is first in the parent list) which would print first then second class's __init__() and then finally __init__() of third class.

MRO prints what I expected.

print(Third.__mro__)

prints

(__main__.Third, __main__.First, __main__.Second, object)
2

2 Answers

1
votes

If you do super().__init__() before you call print(xxx),the order shown is right.

If you want the order showed in the "excepted" tab, you can swap each print(xxx) with super().__init__(),and that will fix it.

Code:

class First(object):
    def __init__(self):
        print("first")
        super().__init__()

class Second(object):
    def __init__(self):
        print("second")
        super().__init__()

class Third(First, Second):
    def __init__(self):
        print("third")            
        super().__init__()
Third()
1
votes

This seems to just be an artifact of when you're printing in __init__. Your current code prints after it calls super().__init__, and so the inheritance hierarchy prints out in reverse order. If you print before the super call, it will be in the same order as the MRO. Perhaps it would be easiest to understand if you printed both ways:

class First(object):
    def __init__(self):
        print("first (top)")
        super().__init__()
        print("first (bottom)")

class Second(object):
    def __init__(self):
        print("second (top)")
        super().__init__()
        print("second (bottom)")

class Third(First, Second):
    def __init__(self):
        print("third (top)")
        super().__init__()
        print("third (bottom)")

Now the output of Third() should be:

third (top)
first (top)
second (top)
second (bottom)
first (bottom)
third (bottom)

The output you see that is <__main__.Third ...> isn't being printed by any of your code, but by the interactive shell. It's the result of calling Third, an instance of the class. If you did instance = Third(), you wouldn't see that, as the value would be stored to the variable, and not printed out. The REPL (Read Eval Print Loop) only runs when Python is runnig interactively, it won't do any extra printing in modules you import or run as a script.