I have these 2 classes:
from avatar import Avatar
class Caster(Avatar):
def __init__(self, name, life, strength, protection, mana):
super().__init__(name, life, strength, protection)
self._mana = mana
and:
from avatar import Avatar
class Melee(Avatar):
def __init__(self, name, life, strength, protection, shield):
super().__init__(name, life, strength, protection)
self._shield = shield
Both of them inherit from:
class Avatar:
def __init__(self, name, life, strength, protection):
self._name = name
self._life = life
self._strength = strength
self._protection = protection
Now I want to create a new class which inherits from both Caster and Melee
from melee import Melee
from caster import Caster
class Chaman(Melee, Caster):
def __init__(self, name, life, strength, protection, shield, mana):
Melee().__init__(self, name, life, strength, protection, shield)
Caster().__init__(self, mana)
This new class combines elements from Melee and Caster. When I execute this and try to create new Chaman objects, it gives me this error:
TypeError: __init__() missing 5 required positional arguments: 'name', 'life', 'strength', 'protection', and 'shield'
CodePudding user response:
Design your classes and use super
correctly, as discussed in further detail at Python's super()
considered super!.
class Avatar:
def __init__(self, *, name, life, strength, protection, **kwargs):
super().__init__(**kwargs)
self._name = name
self._life = life
self._strength = strength
self._protection = protection
class Caster(Avatar):
def __init__(self, *, mana, **kwargs):
super().__init__(**kwargs)
self._mana = mana
class Melee(Avatar):
def __init__(self, *, shield, **kwargs):
super().__init__(**kwargs)
self._shield = shield
class Chaman(Melee, Caster):
pass
# Note that the order of the *keyword* arguments does not matter.
c = Chaman(name="bob", life=3, strength=10, protection=5, mana=9, shield=0)
Each class only deals with the arguments it introduces, passing any others up the stack via super
.
Since Chaman.__init__
isn't defined, Melee.__init__
will be called first; it will call Caster.__init__
(not Avatar.__init__
), which will call Avatar.__init__
, which will call object.__init__
, which will do nothing.