pythoninheritancesuper

How do base-class methods affect output, when invoking `super()`


I was in class section of python programming and I am confused here.

I have learned that super is used to call the method of parent class but here Employee is not a parent of Programmer yet it's called (showing the result of getLanguage method).

What I am missing?

This is the code,

class Employee:
    company= "Google"
    language = "java"
    def showDetails(self):
        print("This is an employee");

    def getLanguage(self):
        print(f"1. The language is {self.language}");


class Programmer:
    language= "Python"
    company = "Youtubeeee"
    def getLanguage(self):
        super().getLanguage();
        print(f"2. The language is {self.language}")

    def showDetails(self):
        print("This is an programmer")



class Programmer2(Programmer , Employee):
    language= "C++"
    def getLanguage(self):
        super().getLanguage();
        print(f"3. The language is {self.language}")



p2 = Programmer2();
p2.getLanguage();

This is the output,

1. The language is C++
2. The language is C++
3. The language is C++

Solution

  • You've bumped into one of the reasons why super exists. From the docs, super delegates method calls to a parent or sibling class of type. Python bases class inheritance on a dynamic Method Resolution Order (MRO). When you created a class with multiple inheritance, those two parent classes became siblings. The left most is first in MRO and the right one is next.

    This isn't a property of the Programmer class, it's a property of the Programmer2 class that decided to do multiple inheritance. If you use Programmer differently, as in,

    p3 = Programmer()
    p3.getLanguage()
    

    You get the error AttributeError: 'super' object has no attribute 'getLanguage' because its MRO only goes to the base object which doesn't have the method.

    You can view the MRO of the class with its __mro__ attribute.

    Programmer.__mro__:
        (<class '__main__.Programmer'>, <class 'object'>)
    
    Programmer2.__mro__:
        (<class '__main__.Programmer2'>, <class '__main__.Programmer'>, 
        <class '__main__.Employee'>, <class 'object'>)