Reputation: 23311
I'm playing with Python Class inheritance and ran into a problem where the inherited __init__
is not being executed if called from the sub-class (code below) the result I get from Active Python is:
>>> start
Tom Sneed
Sue Ann
Traceback (most recent call last):
File "C:\Python26\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 312, <br>in RunScript
exec codeObject in __main__.__dict__
File "C:\temp\classtest.py", line 22, in <module>
print y.get_emp()
File "C:\temp\classtest.py", line 16, in get_emp
return self.FirstName + ' ' + 'abc'
AttributeError: Employee instance has no attribute 'FirstName'
class Person():
AnotherName = 'Sue Ann'
def __init__(self):
self.FirstName = 'Tom'
self.LastName = 'Sneed'
def get_name(self):
return self.FirstName + ' ' + self.LastName
class Employee(Person):
def __init__(self):
self.empnum = 'abc123'
def get_emp(self):
print self.AnotherName
return self.FirstName + ' ' + 'abc'
x = Person()
y = Employee()
print 'start'
print x.get_name()
print y.get_emp()
Upvotes: 16
Views: 24490
Reputation: 11
Using super().init() in a subclass's __init__
method calls the constructor of the parent class, ensuring proper initialization of inherited attributes and avoiding redundancy in the code.
class Employee(Person):
def __init__(self):
self.empnum = 'abc123'
super().__init__()
Upvotes: 1
Reputation: 121
Instead of super(class, instance)
pattern why not just use super(instance)
as the class is always instance.__class__
?
Are there specific cases where it would not be instance.__class__
?
Upvotes: 2
Reputation: 25667
Three things:
This will look like:
class Person(object):
AnotherName = 'Sue Ann'
def __init__(self):
super(Person, self).__init__()
self.FirstName = 'Tom'
self.LastName = 'Sneed'
def get_name(self):
return self.FirstName + ' ' + self.LastName
class Employee(Person):
def __init__(self):
super(Employee, self).__init__()
self.empnum = 'abc123'
def get_emp(self):
print self.AnotherName
return self.FirstName + ' ' + 'abc'
Using super is recommended as it will also deal correctly with calling constructors only once in multiple inheritance cases (as long as each class in the inheritance graph also uses super). It's also one less place you need to change code if/when you change what a class is inherited from (for example, you factor out a base-class and change the derivation and don't need to worry about your classes calling the wrong parent constructors). Also on the MI front, you only need one super call to correctly call all the base-class constructors.
Upvotes: 25
Reputation: 2859
Employee has to explicitly invoke the parent's __init__ (not init):
class Employee(Person):
def __init__(self):
Person.__init__(self)
self.empnum = 'abc123'
Upvotes: 5
Reputation: 29842
You should explicitely call the superclass' init function:
class Employee(Person):
def __init__(self):
Person.__init__(self)
self.empnum = "abc123"
Upvotes: 9