Whenever I run this code I always get a TypeError
that says __init__() missing 1 required positional argument: 'hours'
, but I am not trying to change anything from the original class that the ScientificSwimmer
class is inheriting from…if that makes sense.
Here is the code:
class Human:
def __init__(self, name, age):
self.name = name
self.age = age
def hobby(self):
print("Likes watching Netflix")
def info(self):
print(self.name , "is ",self.age," years old")
class Scientist(Human):
def __init__(self, name, age, lab):
super().__init__(name, age)
self.lab = lab
def hobby(self):
print("Likes doing scientific experiments")
def labName(self,lab):
print("works at the " ,lab, "laboratory")
class Swimmer(Human):
def __init__(self, name, age, hours):
super().__init__(name,age)
self.hours = hours
def hobby(self):
print("likes swimmming in the lake" )
def hoursSwimming(self, hours):
print("swims ", hours , "hours per week")
class ScientificSwimmer(Scientist, Swimmer):
def __init__ (self, name, age, lab, hours):
Scientist.__init__(self,name, age, lab)
Swimmer.__init__(self, name, age, hours)
scienswim = ScientificSwimmer("\nJohn Smith", 30, "nuclear", 100)
scienswim.info()
scienswim.hobby()
scienswim.labName("nuclear")
scienswim.hoursSwimming(100)
My desired result is for it to print:
John smith is 30 years old.
likes doing scientific experiments.
works at the nuclear laboratory.
swims 100 hours per week.
Your original classes simply aren't designed correctly to support cooperative inheritance, which is what super
is designed for. The number one rule for using super
is this: you can't assume you know which class super()
will refer to. That's determined by the runtime type of self
, not the classes you statically inherit from.
Use keyword arguments exclusively to ensure that the method signatures remain compatible, and always call super().__init__
with any unknown keyword arguments (namely, those not explicitly mentioned in the signature).
class Human:
def __init__(self, *, name, age, **kwargs):
super().__init__(**kwargs)
self.name = name
self.age = age
def hobby(self):
print("Likes watching Netflix")
def info(self):
print(self.name , "is ",self.age," years old")
class Scientist(Human):
def __init__(self, *, lab, **kwargs):
super().__init__(**kwargs)
self.lab = lab
def hobby(self):
print("Likes doing scientific experiments")
def labName(self):
print("works at the " , self.lab, "laboratory")
class Swimmer(Human):
def __init__(self, *, hours, **kwargs):
super().__init__(**kwargs)
self.hours = hours
def hobby(self):
print("likes swimmming in the lake" )
def hoursSwimming(self):
print("swims ", self.hours , "hours per week")
class ScientificSwimmer(Scientist, Swimmer):
pass
scienswim = ScientificSwimmer(name="John Smith", age=30, lab="nuclear", hours=100)
scienswim.info()
scienswim.hobby()
scienswim.labName()
scienswim.hoursSwimming()
The method resolution order for ScientificSwimmer
is [ScientificSwimmer, Scientist, Swimmer, Human, object]
. This results in the following:
ScientificSwimmer
need not be defined, as the other __init__
methods will take care of everything. Scientist.__init__
extracts the lab
keyword argument and passes the rest on to the next class. Swimmer.__init__
extracts the hours
keyword argument and passes the rest on to the next class. Human.__init__
extracts the name
and age
keyword arguments and passes the rest on to the next class. object.__init__
receives no keyword arguments, all defined arguments having been correctly extracted by downstream classes.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.