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
not begin a parent of the Programmer
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
CodePudding user response:
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, Its 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'>)
CodePudding user response:
Here is some more explanation about the mechanics how the code in the question works. In its general form, super()
can be called with two arguments super(C, obj)
where C
is a class and obj
is an object. The object obj
determines which classes should be searched for a given attribute and the Method Resolution Order (MRO) in which these classes should be searched. The class argument is used to restrict this search to only these classes that appear in MRO after C
.
By PEP 3135 when super()
is used without arguments inside a class definition, the class argument is automatically taken to be the class being defined, and the object argument is the object upon which super
acts.
In the code in the question, when you call p2.getLanguage()
then inside the definition of Programmer2
, the code super().getLanguage()
is tacitly replaced by super(Programmer2, p2).getLanguage()
. MRO of p2
is Programmer2
-> Programmer
-> Employee
-> object
, and the search for getLanguage
starts after Programmer2
i.e. with Programmer
class, and it succeeds in this class.
Then, in the process of executing getLanguage
method of Programmer
, we again encounter super().getLanguage()
. This is now replaced by super(Programmer, p2).getLanguage()
since we are still working with the same object, but the call to super
is inside Programmer
class. MRO of p2
is still Programmer2
-> Programmer
-> Employee
-> object
, but now the search for getLanguage
starts after Programmer
i.e. with Employee
class, and it succeeds in this class.
In this way, even though Programmer
does not inherit from Employee
, the code super().getLanguage()
inside Programmer
succeeds, since it is applied to an object that has Employee
in its MRO.