I'm only really getting to grips with OOP and I have been looking at multiple inheritance. The problem I have, is when I instantiate the class Hybrid, which inherits from more than one class, I get the following error:
Traceback (most recent call last):
File "multi_inherit.py", line 44, in <module>
hawk = Hybrid('hawk', 200, 650)
File "multi_inherit.py", line 35, in __init__
Archer.__init__(self, name, arrows)
File "multi_inherit.py", line 13, in __init__
super().__init__(name)
TypeError: Wizard.__init__() missing 1 required positional argument: 'power'
The other classes work absolutely fine.
class User:
def __init__(self, name):
self.name = name
def greet(self):
return f"Welcome, {self.name.title()}."
class Archer(User):
def __init__(self, name, arrows):
super().__init__(name)
self.arrows = arrows
def shoot_arrow(self):
self.arrows -= 1
return "You shot an arrow!"
def arrows_left(self):
return f"You have {self.arrows} arrows remaining."
class Wizard(User):
def __init__(self, name, power):
super().__init__(name)
self.power = power
def cast_spell(self):
return f"You cast a spell with a power of {self.power}"
class Hybrid(Archer, Wizard):
def __init__(self, name, arrows, power):
Archer.__init__(self, name, arrows)
Wizard.__init__(self, name, power)
def powerful(self):
return "Hybrids are super powerful!"
merlin = Wizard('merlin', 1000)
robin = Archer('robin', 150)
hawk = Hybrid('hawk', 200, 650)
print(merlin.greet())
print(merlin.cast_spell())
print(robin.arrows_left())
print(robin.shoot_arrow())
print(robin.arrows_left())
superwiht multiple inheritance, then every class should be usingsuper. Your classes have to be designed to support this from the ground up. see: rhettinger.wordpress.com/2011/05/26/super-considered-supersuper(), parameter lists that are different for each class - pick any two, all three simply do not get along. The specific problem is thatsuper()doesn't necessarily invoke the class you expect when there's a diamond in the inheritance graph - so you don't know what set of parameters to pass to it. Explicitly naming the parent class in each inherited call may be the simplest fix here.Archer.__init__(self, name, arrows)whereselfis aHybridobject, then inArcher.__init__, you callsuper().__init__(name). So the MRO ofHybridis[__main__.Hybrid, __main__.Archer, __main__.Wizard, __main__.User, object], so super knows it has a hybrid object, in theArcherclass, so it proxies to the next class in the Hybrid MRO, i.e.Wizard.__init__, but you only passed a single argument, and the second positional argument is missingsuper().__init__(name)withUser.__init__(self, name)it will fix your problem. I don't think this is the proper way of fixing it though; someone else will probably come along with a better answer.