Reputation: 43
I am trying to understand how inheritance works in python. I was looking at a simple code and one thing is confusing me. The code is following:
class Person:
def __init__(self, first, last):
self.firstname = first
self.lastname = last
def Name(self):
return self.firstname + " " + self.lastname
class Employee(Person):
def __init__(self, first, last, staffnum):
Person.__init__(self,first, last)
self.staffnumber = staffnum
def GetEmployee(self):
return self.Name() + ", " + self.staffnumber
x = Person("Marge", "Simpson")
y = Employee("Homer", "Simpson","1007")
print(x.Name())
print(y.GetEmployee())
My question is that when are using Person.__init__()
to call the constructor of baseclass but when we calling Name() method of base class again, instead of using "Person", we are using "self". Can somebody clear this confusion and me understand the how inheritance works in python?
Upvotes: 3
Views: 173
Reputation: 616
The following two methods are equivalent (assuming the "Name" method is never overridden):
class Employee(Person):
def __init__(self, first, last, staffnum):
Person.__init__(self, first, last)
self.staffnumber = staffnum
def getEmployee(self):
return Person.Name(self) + self.staffnumber
class Employee(Person):
def __init__(self, first, last, staffnum):
Person.__init__(self, first, last)
self.staffnumber = staffnum
def getEmployee(self):
return self.Name() + self.staffnumber
In the second example, when self.Name() is called, the instance of the class is "bound" to the function, so the first argument doesn't need to be passed.
Because init is being overridden in the Employee subclass, you can't call self.init(first, last). You'll then call Employee.init(self, *args) rather than Person.init(self, *args). This will either create an infinite recursion loop, or you'll get an argument error.
As a general rule, when you're overriding a method, you have to use the following notation in the subclass. ParentClass.methodname(self, *args, **kwargs). The reason you can call self.Name() is because name has not been overridden.
I'm repeating myself here. Does this crystalize it, or have I confused you further?
Upvotes: 1
Reputation: 251568
The simple way to say it is that self.method()
means "call the most specific implementation of method
available" (i.e., the one furthest down the current object's inheritance tree). In this case you don't wall to call self.__init__
, because that would call Employee.__init__
again. You need to write Person.__init__
(or use super()
) to explicitly call an inherited method.
Because Employee
does not define its own Name
method, Person.Name
is the most specific one available, so that is what is called by self.Name()
. If Employee
defined its own Name
, then that would be called by self.Name()
instead.
Upvotes: 0
Reputation: 4282
The Employee
class inherits methods from the base Person
class, including the __init__
method. So at the top of the class definition, it has __init__
and Name
methods.
Then the Employee
class definition overwrites the __init__
method that it inherited. In order to call the __init__
method of Person
, it has to call Person.__init__
by name (actually, it could use super()
as another alternative).
But since Employee
doesn't overwrite the inherited Name
method, it can use self.Name()
to call the Name
method that it inherited at the top.
Upvotes: 2