QBoard » Big Data » Big Data - Hadoop Eco-System » How does Python's super() work with multiple inheritance?

How does Python's super() work with multiple inheritance?

  • I'm pretty much new in Python object oriented programming and I have trouble understanding the super() function (new style classes) especially when it comes to multiple inheritance.
    For example if you have something like:
    class First(object): def __init__(self): print "first" class Second(object): def __init__(self): print "second" class Third(First, Second): def __init__(self): super(Third, self).__init__() print "that's it"
    What I don't get is: will the Third() class inherit both constructor methods? If yes, then which one will be run with super() and why?
    And what if you want to run the other one? I know it has something to do with Python method resolution order (MRO).
      October 23, 2021 4:28 PM IST
    0
  • Understanding Python super() with __init__() methods [duplicate]

    The reason to use super is so that child classes that may be using cooperative multiple inheritance will call the correct next parent class function in the Method Resolution Order (MRO).

    In Python 3, we can call it like this:

    class ChildB(Base):
    def __init__(self):
    super().__init__()

    In Python 2, you were required to call super like this with the defining class's name and self, but you'll avoid this from now on because it's redundant, slower (due to the name lookups), and more verbose (so update your Python if you haven't already!):

            super(ChildB, self).__init__()

    Without super, you are limited in your ability to use multipleinheritancebecause you hard-wire the next parent's call:

            Base.__init__(self) # Avoid this. This post was edited by paulwings at April 5, 2022 12:18 PM IST
      April 5, 2022 12:16 PM IST
    0
  • Your code, and the other answers, are all buggy. They are missing the super() calls in the first two classes that are required for co-operative subclassing to work.

    Here is a fixed version of the code:

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

     

    The super() call finds the next method in the MRO at each step, which is why First and Second have to have it too, otherwise execution stops at the end of second_init_().

    This is what I get:

    >>> Third()
    second
    first
    third
      November 2, 2021 2:42 PM IST
    0
  • In python 3.5+ inheritance looks predictable and very nice for me. Please looks at this code:

    class Base(object):
      def foo(self):
        print("    Base(): entering")
        print("    Base(): exiting")
    
    
    class First(Base):
      def foo(self):
        print("   First(): entering Will call Second now")
        super().foo()
        print("   First(): exiting")
    
    
    class Second(Base):
      def foo(self):
        print("  Second(): entering")
        super().foo()
        print("  Second(): exiting")
    
    
    class Third(First, Second):
      def foo(self):
        print(" Third(): entering")
        super().foo()
        print(" Third(): exiting")
    
    
    class Fourth(Third):
      def foo(self):
        print("Fourth(): entering")
        super().foo()
        print("Fourth(): exiting")
    
    Fourth().foo()
    print(Fourth.__mro__)

     

    Outputs:

    Fourth(): entering
     Third(): entering
       First(): entering Will call Second now
      Second(): entering
        Base(): entering
        Base(): exiting
      Second(): exiting
       First(): exiting
     Third(): exiting
    Fourth(): exiting
    (<class '__main__.Fourth'>, <class '__main__.Third'>, <class '__main__.First'>, <class '__main__.Second'>, <class '__main__.Base'>, <class 'object'>)

     

    As you can see, it calls foo exactly ONE time for each inherited chain in the same order as it was inherited. You can get that order by calling .mro :

    Fourth -> Third -> First -> Second -> Base -> object
    
    
      November 10, 2021 12:51 PM IST
    0
  • Your code, and the other answers, are all buggy. They are missing the super() calls in the first two classes that are required for co-operative subclassing to work.

    Here is a fixed version of the code:

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

    The super() call finds the next method in the MRO at each step, which is why First and Second have to have it too, otherwise execution stops at the end of Second.__init__().

    This is what I get:

    >>> Third()
    second
    first
    third​
      October 26, 2021 12:48 PM IST
    0