84 python inheritance typeerror method-resolution-order
这是我计划用于游戏的代码.但它抱怨MRO错误.我不知道为什么.有人能为我解释一下吗?非常感谢.
class Player:
pass
class Enemy(Player):
pass
class GameObject(Player, Enemy):
pass
g = GameObject()
Run Code Online (Sandbox Code Playgroud)
Mar*_*ers 109
你GameObject是继承Player 和 Enemy.因为Enemy 已经从PlayerPython 继承现在无法确定首先查找方法的类; 或者Player,或者Enemy,它将覆盖在中定义的东西Player.
您不需要在此命名所有基类Enemy; 只从这一个类继承:
class GameObject(Enemy):
pass
Run Code Online (Sandbox Code Playgroud)
Enemy已包含Player,您不需要再次包含它.
max*_*max 64
我将解释原始代码不起作用的原因.
在查找实例属性/方法时,Python需要决定搜索(直接和间接)基类的顺序.它通过线性化继承图来实现这一点,即通过使用名为C3或MRO的算法将基类图转换为序列.MRO算法是一种独特的算法,可实现多种理想的属性:
A总是出现在班级的孩子面前B,那么A应该出现在之前B("一致的扩展优先顺序")使用您的代码,第二个约束要求Enemy首先出现; 第三个约束要求Player首先出现.由于没有办法满足所有约束,python报告你的继承层次结构是非法的.
如果你GameObject像这样切换基类的顺序,你的代码将会起作用:
class GameObject(Enemy, Player):
pass
Run Code Online (Sandbox Code Playgroud)
这不仅仅是技术细节.在某些(希望很少见)的情况下,如果在多个类中定义方法,您可能需要考虑应该使用哪个类来获取您调用的方法.定义基类的顺序会影响此选择.
你写的是你想成为GameObject一个Player和一个Enemy.但是Enemy已经是一个了Player.该MRO问题只是指出,如果你有一个领域a中Player,在询问这个领域GameObject实例将是不明确的:它应该是a从第一个Player你继承,或从一个Player你通过继承Enemy遗产?
但是你确定你不想使用合成而不是继承吗?
class GameObject(object):
def __init__(self):
self.player = Player()
self.enemy = Enemy()
Run Code Online (Sandbox Code Playgroud)