我遇到以下问题:
Unit
,它有几个属性,例如: id
,type
,
name
,skills
,... health
,attack
或tribe
,因此自然相关的子类HealthUnit
,{{1等等也存在。AttackUnit
或HealthAttackUnit
。我想避免这样编码:
HealthAttackTribeUnit
原因很明显。
我尝试使用dict解压缩作为解决方法,有点像这样:
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)
但即便如此,也会出现大量重复的代码:
class HealthUnit(Unit):
def __init__(self, health, **args):
Unit.__init__(self, **args)
self.health= health
另外,这会多次调用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)
,这不太理想。
所以,问题是:是否有更好的,更少的复制/粘贴方式?
更新: dict解压缩很好,但仍然有点烦人,不得不用关键字参数调用所有构造函数。我不喜欢没有Unit.__init__
的解决方案,但我估计可能没有{?}}?
答案 0 :(得分:4)
是的,这正是super
函数存在的原因。
确保所有__init__
个文件都调用super,Python将为您设计MRO并依次调用相关的类。
class HealthUnit(Unit):
def __init__(self, **kwargs):
self.health = kwargs.pop('health')
super(HealthUnit, self).__init__(**kwargs)
class AttackUnit(Unit):
def __init__(self, **kwargs):
self.attack = kwargs.pop('attack')
super(AttackUnit, self).__init__(**kwargs)
class TribeUnit(Unit):
def __init__(self, **kwargs):
self.tribe = kwargs.pop('tribe')
super(TribeUnit, self).__init__(**kwargs)
class HealthAttackTribeUnit(HealthUnit, AttackUnit, TribeUnit):
pass
另请参阅Python核心贡献者(以及偶尔的SO海报)Raymond Hettinger的文章Super considered super,但请注意该帖子中的语法是针对Python 3的,有一个单独的链接指向版本2代码。