'Multiple Inheritance in Python - TypeError
really struggling with this. It's been bugging for the past couple of days and I cannot get my head around it, nor find an answer that fully makes sense to me.
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 which inherits from more than one class, I get the following error:
TypeError: Wizard.__init__() missing 1 required positional argument: 'power'
The other classes work absolutely fine, it's just when I instantiate the 'Hybrid' class, I get the error.
Here is the code:
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())
Any help would be amazing and any explanations understandable for someone new to this field would be greatly appreciated.
Solution 1:[1]
The classes as you have them now aren't great for use in multiple inheritance. When using multiple inheritance I prefer having constructors that agree on the same contract (use the same arguments) or no arguments at all. Here powers and arrows differ which makes calling each constructor awkward.
IMO A better way to design this class would be mixins. The mixins would have no constructors and depend on particular values being present in the classes which extend them.
Example Mixins:
class UserMixin:
name: str
def greet(self):
return f"Welcome, {self.name.title()}."
class ArcherMixin(UserMixin):
arrows: int
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 WizardMixin(UserMixin):
power: int
def cast_spell(self):
return f"You cast a spell with a power of {self.power}"
Example Implementations:
class User(UserMixin):
def __init__(self, name):
self.name = name
class Archer(ArcherMixin):
def __init__(self, name, arrows):
self.name = name
self.arrows = arrows
class Wizard(WizardMixin):
def __init__(self, name, power):
self.name = name
self.power = power
class Hybrid(ArcherMixin, WizardMixin):
def __init__(self, name, arrows, power):
self.name = name
self.arrows = arrows
self.power = power
def powerful(self):
return "Hybrids are super powerful!"
Example usage:
merlin = Wizard('merlin', 1000)
robin = Archer('robin', 150)
hawk = Hybrid('hawk', 200, 650)
print(merlin.greet())
print(merlin.cast_spell())
print(robin.greet())
print(robin.arrows_left())
print(robin.shoot_arrow())
print(robin.arrows_left())
print(hawk.greet())
print(hawk.cast_spell())
print(hawk.arrows_left())
print(hawk.shoot_arrow())
print(hawk.arrows_left())
Welcome, Merlin.
You cast a spell with a power of 1000
Welcome, Robin.
You have 150 arrows remaining.
You shot an arrow!
You have 149 arrows remaining.
Welcome, Hawk.
You cast a spell with a power of 650
You have 200 arrows remaining.
You shot an arrow!
You have 199 arrows remaining.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | flakes |
