TypeError : 일관된 메서드 확인 순서 (MRO)를 만들 수 없습니다.
이 질문에 이미 답변이 있습니다.
- 이것이 모호한 MRO 인 이유는 무엇입니까? 1 개의 답변
이것은 내 게임에 사용할 코드입니다. 그러나 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 알고리즘은 몇 가지 바람직한 속성을 달성하는 고유 한 알고리즘입니다.
- 각 조상 클래스는 정확히 한 번 나타납니다.
- 클래스는 항상 조상 앞에 나타납니다 ( "단조 론").
- 동일한 클래스의 직계 부모는 클래스 정의에 나열된 것과 동일한 순서로 표시되어야합니다 ( "일관된 로컬 우선 순위").
- 클래스의 아이들이있는 경우
A항상 클래스의 자손 표시B한 후A이전에 나타납니다B( "일관성있는 확장 된 우선 순위")
코드에서 두 번째 제약 조건 Enemy이 먼저 나타나야합니다 . 세 번째 제약은 Player먼저 나타나는 것이 필요합니다 . 모든 제약 조건을 충족시킬 방법이 없기 때문에 파이썬은 상속 계층 구조가 불법이라고보고합니다.
다음 GameObject과 같이 기본 클래스의 순서를 전환하면 코드가 작동합니다 .
class GameObject(Enemy, Player):
pass
이것은 단지 기술적 인 세부 사항이 아닙니다. 드물지만 어떤 경우에는 메서드가 여러 클래스에 정의되어있는 경우 호출 한 메서드를 가져 오기 위해 어떤 클래스를 사용해야하는지 생각할 수 있습니다. 기본 클래스를 정의하는 순서가이 선택에 영향을줍니다.
당신이 쓴 것은 a GameObject가 a Player와 Enemy. 그러나 Enemy는 이미 Player. MRO 문제는에 필드 a가 Player있는 GameObject경우 인스턴스 에서이 필드를 요청하는 것이 모호 할 것임을 나타 냅니다.이 필드가 a처음 Player상속 한 필드 여야 합니까 아니면 Player상속을 통해 상속받은 필드 여야 Enemy합니까?
그러나 상속 대신 구성을 사용하고 싶지 않습니까?
class GameObject(object):
def __init__(self):
self.player = Player()
self.enemy = Enemy()
'Program Club' 카테고리의 다른 글
| JavaScript-HTML 양식 값 가져 오기 (0) | 2020.10.11 |
|---|---|
| 매개 변수를 사용하여 개조 및 GET (0) | 2020.10.11 |
| Axios로 양식에서 파일을 게시하는 방법 (0) | 2020.10.11 |
| Swift에서 UIImage에 색상을 지정하려면 어떻게해야합니까? (0) | 2020.10.10 |
| MySQL my.ini 위치 (0) | 2020.10.10 |