MRO

AI
qwen-3-235b-a22b-instruct-2507
작성자
익명
작성일
2025.09.04
조회수
8
버전
v1

MRO (Method Resolution Order in Python

개요

MRO(Method Resolution Order, 메서드 해석 순서)는 Python에서 다중 상속을 사용할 때, 메서드나 속성이 어떤 순서로 탐색되고 호출되는지를 결정하는 규칙입니다. Python은 다중 상속을 지원하기 때문에, 한 클래스가 여러 부모 클래스를 상속받을 수 있으며, 이 경우 동일한 이름의 메서드가 여러 클래스에 정의되어 있을 수 있습니다. 이때, 어떤 부모 클래스의 메서드를 우선적으로 호출할지 결정하는 것이 MRO의 역할입니다.

Python 2.3 이후로는 C3 선형화(C3 Linearization) 알고리즘을 사용하여 MRO를 계산하며, 이는 일관성 있고 예측 가능한 상속 구조를 보장합니다.


MRO의 필요성

다중 상속은 코드 재사용성과 유연성을 높여주지만, 다음과 같은 모호성(ambiguity) 문제를 초래할 수 있습니다.

class A:
    def method(self):
        print("A의 method")

class B(A):
    def method(self):
        print("B의 method")

class C(A):
    def method(self):
        print("C의 method")

class D(B, C):
    pass

d = D()
d.method()  # 어떤 메서드가 호출될까?

위 코드에서 D 클래스는 BC를 동시에 상속받고 있으며, 두 클래스 모두 method()를 정의하고 있습니다. 이때 Python은 MRO에 따라 B.method()를 호출합니다. 그 이유는 D의 MRO가 D → B → C → A → object 순이기 때문입니다.


MRO 확인 방법

Python에서는 mro() 메서드 또는 [__mro__](/doc/%EA%B8%B0%EC%88%A0/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D/Python/__mro__) 속성을 통해 클래스의 MRO를 확인할 수 있습니다.

print(D.mro())
# 출력: [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]

print(D.__mro__)
# 동일한 결과를 튜플 형태로 반환

또는 내장 함수 help(D)를 사용하여 클래스 정보와 함께 MRO를 확인할 수도 있습니다.


C3 선형화 알고리즘

MRO는 C3 선형화(C3 Linearization) 알고리즘에 따라 계산됩니다. 이 알고리즘은 다음과 같은 조건을 만족해야 합니다:

  1. 자식 클래스는 부모 클래스보다 먼저 온다 (Child before parent)
  2. 왼쪽에서 오른쪽으로 상속된 순서를 유지한다 (Left-to-right consistency)
  3. 모든 클래스가 단일 순서로 정렬되어야 하며, 충돌이 없어야 한다

C3 알고리즘의 기본 원리

클래스 C(B1, B2, ..., BN)의 MRO는 다음과 같은 공식으로 계산됩니다:

MRO(C) = [C] + merge(MRO(B1), MRO(B2), ..., MRO(BN), [B1, B2, ..., BN])

여기서 merge는 각 MRO 리스트와 부모 클래스 리스트를 조합하여 중복 없이 일관된 순서를 만드는 과정입니다. 구체적인 알고리즘은 복잡하지만, Python은 이를 내부적으로 자동으로 처리합니다.


예제: 복잡한 다중 상속 구조

다음은 더 복잡한 상속 구조에서 MRO가 어떻게 작동하는지 보여주는 예제입니다.

class X:
    pass

class Y:
    pass

class Z:
    pass

class A(X, Y):
    pass

class B(Y, Z):
    pass

class M(A, B, Z):
    pass

print(M.mro())

출력 결과:

[<class '__main__.M'>, <class '__main__.A'>, <class '__main__.X'>, <class '__main__.B'>, <class '__main__.Y'>, <class '__main__.Z'>, <class 'object'>]

이 결과는 C3 알고리즘이 X → B → Y 순서를 유지하면서도 충돌 없이 일관된 선형화를 수행했음을 보여줍니다.


super()와 MRO의 관계

super() 함수는 MRO를 기반으로 다음 클래스의 메서드를 호출합니다. 즉, 현재 클래스의 MRO 순서에서 자기 자신 다음에 오는 클래스의 메서드를 호출합니다.

class A:
    def method(self):
        print("A")

class B(A):
    def method(self):
        print("B")
        super().method()

class C(A):
    def method(self):
        print("C")
        super().method()

class D(B, C):
    def method(self):
        print("D")
        super().method()

d = D()
d.method()

출력:

D
B
C
A

이 순서는 D의 MRO(D → B → C → A)에 따라 super()가 다음 클래스로 이동하면서 메서드를 호출하기 때문입니다.


관련 참고 자료


결론

MRO는 Python의 다중 상속에서 핵심적인 역할을 하며, 메서드 호출의 일관성과 예측 가능성을 보장합니다. 개발자는 복잡한 상속 구조를 설계할 때 MRO를 이해하고, super()를 올바르게 사용함으로써 혼란을 방지해야 합니다. mro()를 적극 활용하여 클래스의 메서드 탐색 순서를 확인하고, 디버깅 및 설계 시 참고하는 것이 좋습니다.

AI 생성 콘텐츠 안내

이 문서는 AI 모델(qwen-3-235b-a22b-instruct-2507)에 의해 생성된 콘텐츠입니다.

주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.

이 AI 생성 콘텐츠가 도움이 되었나요?