logo

Python의 메소드 결정 순서

이 튜토리얼에서는 MRO라고도 알려진 메서드 해결 순서에 대해 알아봅니다. 이는 Python 상속의 필수 개념입니다.

메소드 결정 순서는 클래스의 검색 경로를 설명합니다. 파이썬 다중 상속이 포함된 클래스에서 적절한 메서드를 가져오는 데 사용됩니다.

소개

우리가 알고 있듯이 상속되는 클래스를 하위 클래스 또는 상위 클래스라고 하고, 상속하는 클래스를 하위 클래스 또는 하위 클래스라고 합니다. 다중 상속에서는 클래스가 여러 개의 함수로 구성될 수 있으므로 기본 클래스가 실행되는 순서를 검색하기 위해 메서드 결정 순서 기법을 사용합니다.

간단히 말하면 '메서드 또는 속성은 현재 클래스에서 탐색되고, 해당 메소드가 현재 클래스에 없으면 검색이 상위 클래스로 이동하는 식입니다.' 깊이 우선 탐색의 예입니다.

이는 여러 슈퍼클래스에서 동일한 메서드를 찾을 수 있는 다중 상속에서 필수적인 역할을 합니다.

더 나은 방법으로 이해하기 위해 어떻게 사용할 수 있는지 살펴보겠습니다.

예 -

 class A: def myname(self): print('I am a class A') class B(A): def myname(self): print('I am a class B') class C(A): def myname(self): print('I am a class C') c = C() print(c.myname()) 

산출:

 I am a class C 

설명 -

위 코드에는 다중 상속이 있습니다. 우리는 A, B, C라는 3개의 클래스를 정의했으며, 이들 클래스는 다음과 같은 동일한 이름 메서드를 갖습니다. 내 이름(). 우리는 객체 클래스 C를 만들었습니다. 객체는 클래스가 아닌 클래스 C를 호출했고, 클래스 C는 클래스 A 메서드를 상속했습니다.

위 코드에서 따르는 순서는 다음과 같습니다. B급 -> A급. 이 기술을 MRO(메서드 해결 순서)라고 합니다.

np.log

다중 상속의 또 다른 예를 살펴보겠습니다.

예 -

 class A: def myname(self): print(' I am a class A') class B(A): def myname(self): print(' I am a class B') class C(A): def myname(self): print('I am a class C') # classes ordering class D(B, C): pass d = D() d.myname() 

산출:

 I am a class B 

설명 -

위 코드에서는 B, C 클래스를 상속받은 클래스 속성을 정의하지 않고 또 다른 D 클래스를 생성했습니다. 메소드를 호출했을 때 내 이름(), 클래스 D로 가서 다음을 검색합니다. 내 이름( ) 기능. 그러나 클래스 D에는 선언이 없습니다. 따라서 검색은 클래스 B로 이동하여 다음을 얻습니다. 내 이름() 함수를 실행하고 결과를 반환합니다. 검색은 다음과 같이 진행됩니다.

 Class D -> Class B -> Class C -> Class A 

클래스 B에 메서드가 없으면 클래스 C 메서드를 호출합니다.

여기서는 클래스 B 메서드를 제거하고 어떤 일이 일어나는지 확인하는 것이 좋습니다. 이렇게 하면 메소드 분석이 어떻게 작동하는지 알 수 있습니다.

이전 스타일과 새로운 스타일 순서

이전 버전의 Python(2.1)에서는 이전 클래스를 사용하도록 제한되어 있지만 파이썬 (2.2 & 계속) 새 클래스를 사용할 수 있습니다. 기본적으로 Python 3에는 원본(새) 클래스가 있습니다. 새 스타일 클래스의 첫 번째 상위는 Python 루트 '객체' 클래스에서 상속됩니다. 다음 예를 살펴보겠습니다.

예 -

 # Old style class class OldStyleClass: pass # New style class class NewStyleClass(object): pass 

두 클래스의 선언 스타일이 다릅니다. 메서드 결정에서 이전 스타일 클래스는 깊이 우선 왼쪽에서 오른쪽 알고리즘(DLR)을 따르는 반면, 새로운 스타일 클래스는 다중 상속을 수행하는 동안 C3 선형화 알고리즘을 사용합니다.

DLR 알고리즘

Python은 클래스 간의 다중 상속을 구현하는 동안 클래스 목록을 만듭니다. 해당 목록은 인스턴스에서 호출해야 하는 메서드를 결정하는 데 사용됩니다.

메소드 결정이 깊이부터 검색한 다음 왼쪽에서 오른쪽으로 이동하므로 이름으로 작업한다고 가정할 수 있습니다. 아래는 그 예입니다.

자바의 객체 클래스

예 -

 class A: pass class B: pass class C(A, B): pass class D(B, A): pass class E(C,D): pass 

먼저, 알고리즘은 인스턴스 클래스에서 호출된 메서드를 검색합니다. 찾을 수 없으면 첫 번째 부모로 이동하고, 찾을 수 없으면 첫 번째 부모로 이동합니다. 부모의 부모를 조사합니다. 이는 상속 클래스가 끝날 때까지 계속됩니다.

위의 예에서 메서드 해결 순서는 다음과 같습니다.

 class D -> class B -> class A -> class C -> class A 

그러나 A는 두 번 존재할 수 없으므로 -

 class D -> class B -> class A -> class C -> 

이 알고리즘은 당시 이상한 동작을 보여줍니다. 아래 예를 살펴보겠습니다.

예 -

 class A: pass class B: pass class C(A, B): pass class D(B, A): pass class E(C,D): pass 

DLR 알고리즘에 따르면 순서는 E, C, D, B, A입니다. 클래스 C에는 클래스 A와 B가 서로 바뀌는데 이는 매우 모호합니다. 이는 알고리즘이 단조성 속성을 유지하지 않음을 의미합니다.

Samuele Perdoni는 MRO 알고리즘 간의 불일치를 발견한 최초의 사람이었습니다.

C3 선형화 알고리즘

C3 선형화 알고리즘은 불일치를 제거하므로 DLR 알고리즘의 더 나은 버전입니다. 이 알고리즘에는 아래와 같은 몇 가지 제한 사항이 있습니다.

  • 자녀는 부모보다 먼저 있어야 합니다.
  • 특정 클래스가 하나 이상의 클래스에서 상속되는 경우 기본 클래스의 튜플에 지정된 순서대로 저장됩니다.

C3 선형화 알고리즘의 규칙

  • 메소드 결정 순서의 구조는 상속 그래프에 의해 정의됩니다.
  • 사용자는 로컬 클래스의 메소드를 방문한 후에만 슈퍼 클래스를 방문해야 합니다.
  • 단조로움 유지

메소드 결정 클래스의 메소드

Python은 클래스의 메서드 결정 순서를 얻는 두 가지 방법을 제공합니다. __mro__ 속성 또는 미로() 방법. 이러한 방법을 사용하면 문제가 해결된 방법의 순서를 표시할 수 있습니다.

다음 예를 이해해 봅시다.

예 -

 class A: def myname(self): print(' I am a class A') class B(A): def myname(self): print(' I am a class B') class C(A): def myname(self): print('I am a class C') # classes ordering class D(B, C): pass # it prints the lookup order print(D.__mro__) print(C.mro()) 

산출:

 (, , , , ) [, , ] 

위 출력에서 ​​볼 수 있듯이 메서드 해결 순서의 순서를 얻습니다. 이러한 방식으로 C3 선형화 알고리즘은 다중 상속에 작동합니다.