I'm facing the following problem:
- There's a base class
Unit
, which has a couple of attributes, e.g.id
,type
,name
,skills
, ... - There are different types of units, some of them have additional attributes like
health
,attack
, ortribe
, so naturally the relevant subclassesHealthUnit
,AttackUnit
, etc. exist as well. - There are a few units that have multiple of these attributes, e.g.
HealthAttackUnit
, orHealthAttackTribeUnit
.
I want to avoid coding like this:
class Unit(object):
def __init__(self, id, type, name, skills):
self.id= id
self.type= type
self.name= name
self.skills= skills
class HealthUnit(Unit):
def __init__(self, id, type, name, skills, health):
Unit.__init__(self, id, type, name, skills)
self.health= health
class AttackUnit(Unit):
def __init__(self, id, type, name, skills, attack):
Unit.__init__(self, id, type, name, skills)
self.attack= attack
class HealthAttackUnit(HealthUnit, AttackUnit):
def __init__(self, id, type, name, skills, health, attack):
HealthUnit.__init__(self, id, type, name, skills, health)
AttackUnit.__init__(self, id, type, name, skills, attack)
for obvious reasons.
I tried to use dict unpacking as a workaround, kind of like this:
class HealthUnit(Unit):
def __init__(self, health, **args):
Unit.__init__(self, **args)
self.health= health
but even this comes with lots of duplicate code:
class HealthAttackUnit(HealthUnit, AttackUnit):
def __init__(self, health, attack, **args):
HealhUnit.__init__(self, health=health, **args)
AttackUnit.__init__(self, attack=attack, **args)
class HealthAttackTribeUnit(HealthUnit, AttackUnit, TribeUnit):
def __init__(self, health, attack, tribe, **args):
HealhUnit.__init__(self, health=health, **args)
AttackUnit.__init__(self, attack=attack, **args)
TribeUnit.__init__(self, tribe=tribe, **args)
Plus, this will call Unit.__init__
multiple times, which is less than ideal.
So, the question is: Is there a better, less copy/paste, way of doing this?
Update: The dict unpacking is nice and all, but it's still a little annoying having to call all constructors with keyword arguments. I'd prefer a solution without **kwargs
, but I'm guessing there probably isn't one?