我面临以下问题:
- 有一个基类
Unit
,它有几个属性,例如id
、类型
、姓名
、技能
、... - 有不同类型的单位,其中一些具有附加属性,例如
health
、attack
或tribe
,因此自然也有相关的子类HealthUnit
、AttackUnit
等也存在。 - 有一些单位具有多个这些属性,例如
HealthAttackUnit
或HealthAttackTribeUnit
。
我想避免这样的编码:
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)
另外,这会多次调用 Unit.__init__
,这不太理想。
所以,问题是:有没有更好的、更少复制/粘贴的方法来做到这一点?
更新: 字典解包很好,但是必须使用关键字参数调用所有构造函数仍然有点烦人。我更喜欢一种没有 **kwargs
的解决方案,但我猜可能没有?
最佳答案
是的,这正是 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 代码的单独链接。
关于python - 如何正确使用多重(重新)继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26890762/