다중 상속과 메서드 결정 순서

매일 공부(ML)·2023년 2월 14일
0

Fluent Python

목록 보기
82/130

객체지향 상용구

내장 자료형 상속과 다중 상속

다중 상속과 메서드 결정 순서

다중 상속을 지원하는 언어에선 별개의 상위클래스가 동일한 이름으로 메서드를 구현하 ㄹ때 발생하는 이름 충돌 문제(다이아몬드 문제)를 해결해야 한다.


"""
B클래스와 C클래스 모두 pong() 메서드를 구현하고 있지만, C.pong() 메서드는 대문자로 출력한다는 것이 다르다.
"""
class A:
	def ping(self):
    	print('ping:', self)
        
class B(A):
	def pong(self):
    	print("pong", self)

class C(A):
	def pong(self):
    	print("pong", self)
        
class D(B,C):
	def ping(self):
    	super().ping()
        print("post-ping:", self)
        
    def pingpong(self):
    	self.ping()
        super().ping()
        self.pong()
        super().pong()
        C.pong(self)

D클래스 객체의 pong() 메서드를 호출하는 두 가지 방법

from diamond import *
d = D()
d.pong()
C.pong(d)

파이썬이 상속 그래프를 조회할 때는 특정한 순서를 따르고, d.pong()과 같은 호출의 모호함이 해결되고, 이 순서를 메서드 결정 순서(MRO)라고 한다. 클래스에 있는 mro속성은 현재 클래스부터 object 클래스까지 슈퍼 클래스들의 MRO를 튜플 형태로 저장한다.


슈퍼클래스 메서드에 위힘할 때는 내장 함수인 super()를 사용하는 것이 좋다

def ping(self):
	A.ping(self) # super().ping() 대신 호출
    print('post-ping:', self)

객체 메서드를 클래스에 직접 호출할 때는 self를 반드시 명시해야 하고, 바인딩되지 않은 메서드에 접근하는 것이기 때문이다. 그러나, 프레임워크 혹은 여러분이 직접 제어할 수 없는 클래스 계층 구조에 들어 있는 메서드를 호출할 때는 super()를 사용하는 것이 안전하며, 향우 프레임워크가 변경 되어도 문제없이 작동한다.

from diamond import D
d = D()
d.ping()
profile
성장을 도울 아카이빙 블로그

0개의 댓글