TypeError: no se puede crear un orden de resolución de método (MRO) consistente

Este es el código que planeo usar para mi juego. Pero se queja por un error de MRO. No se por que ¿Puede alguien explicarme por mí? Muchas gracias.

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

Tu GameObject está heredando de Player y Enemy . Debido a que Enemy ya hereda de Player Python ahora no puede determinar qué clase buscar primero en los métodos; ya sea Player , o en Enemy , que anularía las cosas definidas en Player .

No necesitas nombrar todas las clases base de Enemy aquí; simplemente heredar de esa clase:

 class GameObject(Enemy): pass 

Enemy ya incluye Player , no necesitas incluirlo de nuevo.

Explicaré la razón por la que el código original no funciona.

Python debe decidir en qué orden buscar las clases base (directas e indirectas) al buscar un atributo / método de instancia. Lo hace linealizando el gráfico de herencia, es decir, convirtiendo el gráfico de clases base en una secuencia, utilizando un algoritmo llamado C3 o MRO . El algoritmo MRO es el algoritmo único que logra varias propiedades deseables:

  1. Cada clase ancestral aparece exactamente una vez.
  2. una clase siempre aparece antes de su antepasado (“monotonicidad”)
  3. los padres directos de la misma clase deben aparecer en el mismo orden en que aparecen en la definición de la clase (“orden de precedencia local coherente”)
  4. si los hijos de clase A siempre aparecen antes que los hijos de clase B , entonces A debería aparecer antes de B (“orden de prioridad extendido consistente”)

Con tu código, la segunda restricción requiere que aparezca Enemy primero; la tercera restricción requiere que el Player aparezca primero. Como no hay forma de satisfacer todas las restricciones, Python informa que su jerarquía de herencia es ilegal.

Tu código funcionará si GameObject el orden de las clases base en GameObject así:

 class GameObject(Enemy, Player): pass 

Esto no es sólo un detalle técnico. En algunos casos (con suerte raros), es posible que desee pensar qué clase debería usarse para tomar el método al que llamó si el método está definido en varias clases. El orden en que se definen las clases base afecta esta elección.

Lo que escribiste es que quieres que un GameObject sea ​​tanto un Player como un Enemy . Pero un Enemy ya es un Player . El problema de MRO simplemente indica que si tuvieras un campo en Player , pedir este campo en una instancia de GameObject sería ambiguo: si fuera el nombre del primer Player que heredas o el del Player que heredas a través de tu herencia Enemy ?

Pero, ¿estás seguro de que no quieres usar la composición en lugar de la herencia aquí?

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