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'
Chandan
  • 571
  • 4
  • 21
Owen Boorn
  • 61
  • 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__()`. – jasonharper Feb 04 '21 at 02:28

4 Answers4

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

wjandrea
  • 28,235
  • 9
  • 60
  • 81
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'}


Eric Truett
  • 2,970
  • 1
  • 16
  • 21
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.
pakpe
  • 5,391
  • 2
  • 8
  • 23
  • 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. – D Hudson Feb 10 '21 at 12:00
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")

KennetsuR
  • 704
  • 8
  • 17