6

So I'm currently learning about python's inheritance for one of my classes and the assignment has us use multiple inheritances for the ScientificSwimmer Class. When you try to run the code without creating an object of said class the program runs. However, when creating an object of that class I get the error below. Any advice or solutions would be greatly appreciated. (Line numbers added in post)

#creation of Human class
class Human: 
 def __init__(self, name, age): #talks a name and balance and creates a instance of class
 self.age = age
 self.name = name
 
 def hobby(self):#Hobby method
 print("Likes to watch Netflix")
 
 def info(self):#info method
 print(self.name, " is ", self.age, " years old.")
 
#creation of the Scientist class
class Scienctist(Human):
 
 def __init__(self, name, age, lab):
 super().__init__(name, age)
 self.lab = lab
 
 def hobby(self):
 print("Likes watching Bill Nye the science guy.")
 
 def labName(self):
 print("Works at the ", self.lab , "laboratory.")
 
#Creation of Swimmer Class
class Swimmer(Human):
 
 def __init__(self, name, age, hours):
(line 33)super().__init__(name, age)
 self.hours = hours
 
 def hobby(self):
 print("Likes to go swimming in the lake.")
 
 def SwimmingHours(self):
 print("Swims ", self.hours, "hours per week.")
 
#Creation of the ScientificSwimmer
class ScientificSwimmer(Scienctist, Swimmer):
 def __init__(self, name, age, lab, hours):
(line 58)Scienctist.__init__(self, name, age, lab)
 Swimmer.__init__(self, name, age, hours)
(line 66) person5 = ScientificSwimmer("John Smith", "30", "nuclear", "100")

Error:

File "E:\Python\CS112\lab7\People.py", line 66, in <module>
 person5 = ScientificSwimmer("John Smith", "30", "nuclear", "100")
 File "E:\Python\CS112\lab7\People.py", line 58, in __init__
 Scienctist.__init__(self, name, age, lab)
 File "E:\Python\CS112\lab7\People.py", line 33, in __init__
 super().__init__(name, age)
TypeError: __init__() missing 1 required positional argument: 'hours'
asked Feb 4, 2021 at 2:17
1
  • 3
    You have to use super() for invoking inherited methods either consistently, or not at all. And you can't use it consistently in cases like this, that involve multiple inheritance and parameter lists that aren't the same as the inherited version of the method. There are probably other solutions, but I'd suggest replacing all super()s with the explicit name of the parent class, as you did in ScientificSwimmer.__init__(). Commented Feb 4, 2021 at 2:28

4 Answers 4

1

You have to use super() for invoking inherited methods either consistently, or not at all. And you can't use it consistently in cases like this, that involve multiple inheritance and parameter lists that aren't the same as the inherited version of the method. There are probably other solutions, but I'd suggest replacing all super()s with the explicit name of the parent class, as you did in ScientificSwimmer.__init__().

-- comment by jasonharper

Sign up to request clarification or add additional context in comments.

Comments

1

I would change the classes to add a **kwargs parameter for each one. This is the simplest way of handling the different parameters.

#creation of Human class
class Human:
 def __init__(self, name, age, **kwargs): #talks a name and balance and creates a instance of class
 self.age = age
 self.name = name
 def hobby(self):#Hobby method
 print("Likes to watch Netflix")
 def info(self):#info method
 print(self.name, " is ", self.age, " years old.")
#creation of the Scientist class
class Scienctist(Human):
 def __init__(self, name, age, lab, **kwargs):
 super().__init__(name, age, **kwargs)
 self.lab = lab
 def hobby(self):
 print("Likes watching Bill Nye the science guy.")
 def labName(self):
 print("Works at the ", self.lab , "laboratory.")
#Creation of Swimmer Class
class Swimmer(Human):
 def __init__(self, name, age, hours, **kwargs):
 super().__init__(name, age, **kwargs)
 self.hours = hours
 def hobby(self):
 print("Likes to go swimming in the lake.")
 def SwimmingHours(self):
 print("Swims ", self.hours, "hours per week.")
#Creation of the ScientificSwimmer
class ScientificSwimmer(Scienctist, Swimmer):
 def __init__(self, name, age, lab, hours, **kwargs):
 super().__init__(name=name, age=age, lab=lab, hours=hours, **kwargs)

Output

>>> person5 = ScientificSwimmer("John Smith", "30", "nuclear", "100")
>>> person5
<__main__.ScientificSwimmer at 0x248ca7fb730>
>>> vars(person5)
{'age': '30', 'name': 'John Smith', 'hours': '100', 'lab': 'nuclear'}
answered Feb 4, 2021 at 2:48

Comments

1

With messy multiple inheritance patterns like this where parents classes share some instance attributes, it is best to declare the parent inits explicitly in each class:

class Human:
 def __init__(self, name, age): # talks a name and balance and creates a instance of class
 self.age = age
 self.name = name
 def hobby(self): # Hobby method
 print("Likes to watch Netflix")
 def info(self): # info method
 print(self.name, " is ", self.age, " years old.")
class Scienctist(Human):
 def __init__(self, name, age, lab):
 Human.__init__(self, name, age)
 self.lab = lab
 def hobby(self):
 print("Likes watching Bill Nye the science guy.")
 def labName(self):
 print("Works at the ", self.lab, "laboratory.")
class Swimmer(Human):
 def __init__(self, name, age, hours):
 Human.__init__(self,name, age)
 self.hours = hours
 def hobby(self):
 print("Likes to go swimming in the lake.")
 def swimmingHours(self):
 print("Swims ", self.hours, "hours per week.")
class ScientificSwimmer(Scienctist, Swimmer):
 def __init__(self, name, age, lab, hours):
 Scienctist.__init__(self, name, age, lab)
 Swimmer.__init__(self, name, age, hours)
person = ScientificSwimmer("John Smith", 30, "nuclear", 100)
person.labName()
person.swimmingHours()
#Works at the nuclear laboratory.
#Swims 100 hours per week.
answered Feb 4, 2021 at 4:38

1 Comment

Good point, pointing out that this approach is messy. @Owen Boorn, I understand that this is an assignment so you may not have a choice here; in the real world, you'd be much better off using composition rather than inheritance precisely due to these sorts of complexities and maintenance overheads.
0
# creation of Human class
class Human:
 def __init__(self, name, age): # talks a name and balance and creates a instance of class
 if hasattr(self, 'age'):
 return
 if hasattr(self, 'name'):
 return
 self.age = age
 self.name = name
 def hobby(self): # Hobby method
 print("Likes to watch Netflix")
 def info(self): # info method
 print(self.name, " is ", self.age, " years old.")
# creation of the Scientist class
class Scienctist(Human):
 def __init__(self, lab, **kw):
 super().__init__(**kw)
 self.lab = lab
 def hobby(self):
 print("Likes watching Bill Nye the science guy.")
 def labName(self):
 print("Works at the ", self.lab, "laboratory.")
# Creation of Swimmer Class
class Swimmer(Human):
 def __init__(self, hours, **kw):
 super().__init__(**kw)
 self.hours = hours
 def hobby(self):
 print("Likes to go swimming in the lake.")
 def SwimmingHours(self):
 print("Swims ", self.hours, "hours per week.")
# Creation of the ScientificSwimmer
class ScientificSwimmer(Scienctist, Swimmer):
 def __init__(self, name, age, lab, hours):
 super(ScientificSwimmer, self).__init__(name=name, age=age, lab=lab, hours=hours)
if __name__ == '__main__':
 person5 = ScientificSwimmer(name="John Smith", age="30", lab="nuclear", hours="100")
answered Feb 4, 2021 at 2:43

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.