CodeGym /행동 /Python SELF KO /메서드 해결 순서 (MRO)

메서드 해결 순서 (MRO)

Python SELF KO
레벨 16 , 레슨 5
사용 가능

11.1 Method Resolution Order

메서드 해결 순서 (Method Resolution Order, MRO)는 Python이 클래스 계층 구조에서 메서드와 속성을 찾는 순서를 결정해. 이건 특히 다중 상속을 사용할 때 중요하거든, 클래스가 여러 부모 클래스에서 속성과 메서드를 상속 받을 수 있잖아.

쉽게 말해서, Python이 클래스 상속 트리를 어떻게 탐색하는지에 대한 엄격한 고정된 순서(혹은 알고리즘)가 있어. 이 알고리즘은 메서드를 찾는 올바른 순서를 보장해, 이걸 다음과 같이 설명할 수 있어:

C3 선형화 알고리즘

C3 선형화 알고리즘은 다음을 결합하여 MRO를 결정해:

  • 자신의 클래스.
  • 부모 클래스 리스트를 나열된 순서대로.
  • 부모 클래스의 MRO를 같은 순서로.

C3 선형화 알고리즘 규칙

  • 메서드의 로컬 순서를 유지하기: 클래스 A가 클래스 B 앞에 나열되면, 클래스 A의 모든 메서드는 클래스 B의 메서드보다 먼저 고려되어야 해.
  • 부모 클래스 순서 유지하기: 클래스 A가 클래스 B의 부모라면, 클래스 A의 모든 메서드는 클래스 B의 메서드보다 먼저 고려되어야 해.
  • 상속 순서 고려하기: 클래스 C가 두 개 이상의 클래스의 부모라면, 클래스 C의 메서드 순서는 이 모든 클래스의 MRO에서 유지되어야 해.

알고리즘 단계:

1단계. 자신 클래스부터 시작하기:

언제나 메서드를 호출한 자신 클래스부터 시작해.

2단계. 기본 클래스들을 나열된 순서대로 추가하기:

현재 클래스 다음으로 기본 클래스들을 상속된 순서대로 확인해.

3단계. 부모 클래스 탐색하기:

필드와 메서드를 그곳에서 찾아봐.

4단계. 부모 클래스의 MRO 병합하기:

동일한 기본 클래스가 여러 경로로 상속되더라도, 그 클래스는 한 번만 올바른 순서로 확인되고 나머지는 생략 돼.

"알고리즘과 데이터 구조"에 친숙한 이들에게는 깊이 우선 탐색이지, 너비 우선 탐색이 아니라.

11.2 MRO 확인하기

Python에서 클래스의 메서드와 필드 탐색 순서를 __mro__ 속성이나 mro() 함수를 사용하여 확인할 수 있어.

예시:


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

# MRO 확인하기
print(D.__mro__)
        

출력 결과:


(<class '__main__.D'>, 
<class '__main__.B'>, 
<class '__main__.C'>,
<class '__main__.A'>,
<class 'object'>)
        

이것은 Python이 메서드와 속성을 찾는 순서를 보여줘:

  • D: Python은 먼저 클래스 D에서 메서드를 확인해.
  • B: 그 다음 Python은 첫 번째 부모 클래스인 B에서 메서드를 확인해.
  • C: 메서드가 클래스 B에서 발견되지 않으면, Python은 두 번째 부모 클래스인 C에서 메서드를 확인해.
  • A: 메서드가 BC에서 발견되지 않으면, Python은 클래스 A에서 메서드를 확인해.
  • object: 마지막으로 Python은 기본 클래스 object에서 메서드를 확인해.

11.3 MRO와 함께 super() 사용하기

super() 함수는 부모 클래스 메서드를 올바른 순서로 호출하기 위해 MRO를 따르게 해. super() 사용 예제를 살펴보자:

class A:
    def method(self):
        print("A")
        super().method()
        
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
        

탐색 순서 (MRO)

1. method 메서드의 클래스 D 호출:

  • Python은 클래스 D에서 메서드를 확인하고, 메서드를 찾아.
  • D.method()가 실행되고 "D"를 출력해.
  • 그 다음 super().method()가 호출되며 다음 메서드를 호출하기 위해 MRO를 따라가.

2. method 메서드의 클래스 B 호출:

  • MRO에 따라, D 다음 클래스는 B야.
  • B.method()가 실행되고 "B"를 출력해.
  • 그 다음 super().method()가 호출되며 다음 메서드를 호출하기 위해 MRO를 따라가.

3. method 메서드의 클래스 C 호출:

  • MRO에서 B 다음 클래스는 C야.
  • C.method()가 실행되고 "C"를 출력해.
  • 그 다음 super().method()가 호출되며 다음 메서드를 호출하기 위해 MRO를 따라가.

4. method 메서드의 클래스 A 호출:

  • MRO에서 C 다음 클래스는 A야.
  • A.method()가 실행되고 "A"를 출력해.
  • 그 다음 super().method()가 호출되지만 A에는 부모의 method 메서드가 없기 때문에 (기본 클래스 object 제외), 호출은 추가적인 동작 없이 끝나.
1
설문조사/퀴즈
상속, 레벨 16, 레슨 5
사용 불가능
상속
상속
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION