TypeError:无法创建一致的方法解析顺序(MRO)



这是我计划在游戏中使用的代码,但它抱怨MRO错误:

class Player:
    pass
class Enemy(Player):
    pass
class GameObject(Player, Enemy):
    pass
g = GameObject()

您的GameObject继承自PlayerEnemy。因为Enemy已经继承自PlayerPython现在无法确定首先查找方法的类;PlayerEnemy,这将覆盖Player中定义的内容。

您不需要在这里命名Enemy的所有基类;只需继承一个类:

class GameObject(Enemy):
    pass

Enemy已经包含Player,您不需要再包含它。

我将解释原始代码不起作用的原因。

在查找实例属性/方法时,Python需要决定搜索(直接和间接)基类的顺序。它通过线性化继承图来实现这一点,也就是说,使用一种称为C3或MRO的算法,将基类的图转换为序列。MRO算法是一种独特的算法,它实现了几个理想的特性:

  1. 每个祖先类只出现一次
  2. 类总是出现在其祖先之前("单调性")
  3. 同一类的直接父类应按照类定义中列出的顺序出现("一致的局部优先顺序")
  4. 如果类A的子级总是出现在类B的子级之前,则A应该出现在B之前("一致的扩展优先级顺序")

对于您的代码,第二个约束要求Enemy首先出现;第三个约束要求CCD_ 17首先出现。由于无法满足所有约束,python报告您的继承层次结构是非法的。

如果你像这样切换GameObject中基类的顺序,你的代码就会工作:

class GameObject(Enemy, Player):
    pass

这不仅仅是一个技术细节。在某些情况下(希望是罕见的),如果方法在多个类中定义,您可能需要考虑应该使用哪个类来获取您调用的方法。定义基类的顺序会影响此选择。

您所写的是希望GameObject既是Player又是Enemy。但是CCD_ 22已经是CCD_。MRO问题只是指出,如果您在Player中有一个字段a,那么在GameObject实例中请求该字段将是不明确的:它是您继承的第一个Player中的a,还是您通过Enemy继承的Player中的CCD27?

但是你确定你不想使用组合而不是继承吗?

class GameObject(object):
    def __init__(self):
        self.player = Player()
        self.enemy = Enemy()

相关内容

  • 没有找到相关文章

最新更新