문제
부모 클래스를 상속받은 자식 클래스에서 부모의 메소드를 실행하고자 할 때.
해결
super()를 사용하여 쉽게 부모 클래스의 함수를 실행하자.
코드
좋지 않은 예시.
상속 계층이 깊어질 때, 다중 상속일 경우일 때,
직계 부모 클래스를 지정하여 실행하면 불필요하게 메소드가 실행되는 것을 볼 수 있다.
# Tricky initialization problem involving multiple inheritance.
# Does NOT use super()
class Base:
def __init__(self):
print('Base.__init__')
class A(Base):
def __init__(self):
Base.__init__(self)
print('A.__init__')
class B(Base):
def __init__(self):
Base.__init__(self)
print('B.__init__')
class C(A,B):
def __init__(self):
A.__init__(self)
B.__init__(self)
print('C.__init__')
if __name__ == '__main__':
# Please observe double call of Base.__init__
c = C()
# results
'''
Base.__init__
A.__init__
Base.__init__
B.__init__
C.__init__
'''
좋은 예시.
root위치에 있는 부모인 Base 클래스가 두 번 호출된 위의 예시와 다르게
super()를 통하여, 모든 부모 메소드를 호출했고, 한 번씩 실행되도록 변경되었다.
# Tricky initialization problem involving multiple inheritance.
# Uses super()
class Base:
def __init__(self):
print('Base.__init__')
class A(Base):
def __init__(self):
super().__init__()
print('A.__init__')
class B(Base):
def __init__(self):
super().__init__()
print('B.__init__')
class C(A,B):
def __init__(self):
super().__init__() # Only one call to super() here
print('C.__init__')
if __name__ == '__main__':
# Observe that each class initialized only once
c = C()
# results
'''
Base.__init__
B.__init__
A.__init__
C.__init__
'''
MRO(Method Resolution Order)
super() 메소드는 자식 클래스가 상속한 모든 부모 계층의 클래스를 MRO 리스트로 정렬한다.
MRO 리스트에 대해 모든 메소드가 한 번만 호출된다.
MRO에 대해 재밌게 설명한 글이 있어서 첨부한다.
https://tibetsandfox.tistory.com/26
뭐가 좋은가?
불필요하게 부모의 메소드를 호출하지 않을 수 있다.
상속받은 부모 클래스가 없어도 에러를 내지 않는다(모든 클래스의 부모는 Python Object 클래스이기 때문)
출처: Beazley, D., & Jones, B. K. (2013). *Python cookbook* (3rd ed., pp. 227–230). O’Reilly Media
'Development > Python-Cookbook' 카테고리의 다른 글
| 8.3 객체의 컨텍스트 관리 프로토콜 지원 (1) | 2025.03.29 |
|---|---|
| 7.8 인자를 N개 받는 함수를 더 적은 인자로 사용 (0) | 2025.02.15 |