python - 如何正确使用多重(重新)继承

标签 python python-2.7 inheritance multiple-inheritance

我面临以下问题:

  • 有一个基类 Unit,它有几个属性,例如id类型姓名技能、...
  • 有不同类型的单位,其中一些具有附加属性,例如 healthattacktribe,因此自然也有相关的子类HealthUnitAttackUnit 等也存在。
  • 有一些单位具有多个这些属性,例如HealthAttackUnitHealthAttackTribeUnit

我想避免这样的编码:

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/

相关文章:

python - 使用传递的参数作为 django 中查询字符串中的值

python - 正确初始化列表

python - 虚拟环境中的 Opencv3 和 Python 2.7 - AttributeError : 'module' object has no attribute 'createLBPHFaceRecognizer'

c++ - 有没有一种用额外的运算符扩展类的好方法?

typescript - Typescript 通用参数的模式有时可能是未定义的?

c# - 如何在从抽象类派生的类中创建新方法?

python - 如何允许用户在 Django Rest Framework 中仅修改他的数据

javascript - 将 JavaScript date() 转换为 Python Django models.DateTimeField

python - 获取 Scrapy 记录器

python - 为什么 super().__init__ 在子类化 threading.Thread 时不起作用?