TypeError: Cannot create a consistent method resolution

问题

class Player:
    pass


class Enemy(Player):
    pass


class GameObject(Player, Enemy):
    pass


g = GameObject()

# 执行代码报错如下
Traceback (most recent call last):
  File "D:/wang/pyCode/exersice_python/OOP_inheritance.py", line 110, in <module>
    class GameObject(Player, Enemy):
TypeError: Cannot create a consistent method resolution
order (MRO) for bases Player, Enemy



修改GameObject类的声明顺序后,代码正常运行。

class Player:
    pass


class Enemy(Player):
    pass


class GameObject(Enemy, Player):  # 解决方法一
    pass


class GameObject2(Enemy):  # 解决方法二
    pass


g = GameObject()
g2 = GameObject2()



问题解析

I’ll explain the reason the original code doesn’t work.

Python needs to decide in which order to search through (direct and indirect) base classes when looking up an instance attribute / method. It does this by linearizing the inheritance graph, that is by converting the graph of base classes into a sequence, using an algorithm called C3 or MRO. The MRO algorithm is the unique algorithm that achieves several desirable properties:

  1. each ancestor class appears exactly once
  2. a class always appears before its ancestor (“monotonicity”) 【单调性】
  3. direct parents of the same class should appear in the same order as they are listed in class definition (“consistent local precedence order”) 【本地优先级,访问时与类中的声明顺序一致】
  4. if children of class A always appear before children of class B, then A should appear before B (“consistent extended precedence order”)

With your code, the second constraint requires that Enemy appears first; the third constraint requires that Player appears first. Since there’s no way to satisfy all constraints, python reports that your inheritance hierarchy is illegal.

Your code will work if you switch the order of base classes in GameObject like so:

class GameObject(Enemy, Player):
pass

This is not just a technical detail. In some (hopefully rare) cases, you might want to think about which class should be used to grab the method you called if the method is defined in multiple classes. The order in which you define base classes affects this choice.


参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值