Program Club

TypeError : 일관된 메서드 확인 순서 (MRO)를 만들 수 없습니다.

proclub 2020. 10. 11. 11:31
반응형

TypeError : 일관된 메서드 확인 순서 (MRO)를 만들 수 없습니다.


이 질문에 이미 답변이 있습니다.

이것은 내 게임에 사용할 코드입니다. 그러나 MRO 오류에 대해 불평합니다. 이유를 모르겠습니다. 누군가 나를 위해 설명 할 수 있습니까? 감사합니다.

class Player:
    pass

class Enemy(Player):
    pass

class GameObject(Player, Enemy):
    pass

g = GameObject()

당신은 GameObject에서 상속 Player 하고 Enemy . 왜냐하면 Enemy 이미Player 파이썬 에서 상속받은 것은 이제 어떤 클래스에서 먼저 메서드를 찾을 지 결정할 수 없기 때문입니다. 정의 된 항목을 재정의하는 Player, 또는 on .EnemyPlayer

Enemy여기서 모든 기본 클래스의 이름을 지정할 필요는 없습니다 . 그 하나의 클래스에서 상속하십시오.

class GameObject(Enemy):
    pass

Enemy이미 포함되어 있으므로 Player다시 포함 할 필요가 없습니다.


원래 코드가 작동하지 않는 이유를 설명하겠습니다.

Python은 인스턴스 속성 / 메서드를 찾을 때 기본 클래스 (직접 및 간접)를 검색 할 순서를 결정해야합니다. C3 또는 MRO 라는 알고리즘을 사용하여 상속 그래프를 선형화합니다. 즉, 기본 클래스의 그래프를 시퀀스로 변환합니다 . MRO 알고리즘은 몇 가지 바람직한 속성을 달성하는 고유 한 알고리즘입니다.

  1. 각 조상 클래스는 정확히 한 번 나타납니다.
  2. 클래스는 항상 조상 앞에 나타납니다 ( "단조 론").
  3. 동일한 클래스의 직계 부모는 클래스 정의에 나열된 것과 동일한 순서로 표시되어야합니다 ( "일관된 로컬 우선 순위").
  4. 클래스의 아이들이있는 경우 A항상 클래스의 자손 표시 B한 후 A이전에 나타납니다 B( "일관성있는 확장 된 우선 순위")

코드에서 두 번째 제약 조건 Enemy이 먼저 나타나야합니다 . 세 번째 제약은 Player먼저 나타나는 것이 필요합니다 . 모든 제약 조건을 충족시킬 방법이 없기 때문에 파이썬은 상속 계층 구조가 불법이라고보고합니다.

다음 GameObject과 같이 기본 클래스의 순서를 전환하면 코드가 작동합니다 .

class GameObject(Enemy, Player):
    pass

이것은 단지 기술적 인 세부 사항이 아닙니다. 드물지만 어떤 경우에는 메서드가 여러 클래스에 정의되어있는 경우 호출 한 메서드를 가져 오기 위해 어떤 클래스를 사용해야하는지 생각할 수 있습니다. 기본 클래스를 정의하는 순서가이 선택에 영향을줍니다.


당신이 쓴 것은 a GameObject가 a PlayerEnemy. 그러나 Enemy는 이미 Player. MRO 문제는에 필드 aPlayer있는 GameObject경우 인스턴스 에서이 필드를 요청하는 것이 모호 할 것임을 나타 냅니다.이 필드가 a처음 Player상속 한 필드 여야 합니까 아니면 Player상속을 통해 상속받은 필드 여야 Enemy합니까?

그러나 상속 대신 구성을 사용하고 싶지 않습니까?

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

참고 URL : https://stackoverflow.com/questions/29214888/typeerror-cannot-create-a-consistent-method-resolution-order-mro

반응형