#자식 인스턴스에서 부모 클래스의 __init__ 메서드를 직접 호출
#부모 클래스 초기화
#다중 상속에 영향을 받은 클래스가 있다면 잘 작동하지 않는다>
class MyBaseClass:
def __init__(self, value):
self.value = value
class MyChildClass(MyBaseClass):
def __init__(self):
MyBaseClass.__init__(self,5)
"다중 상속으로 인해 발생하는 문제: 모든 하위 클래스에서 __init__호출의 순서가 정해짐X 이로 인해서 예측할 수 없는 방식으로 작동"""
class TimesTwo:
def __init__(self):
self.value *= 2
class PlusFive:
def __init__(self):
self.value +=5
class OneWay(MyBaseClass, TimesTwo, PlusFive):
def __init__(self, value):
MyBaseClass.__init__(self, value)
TimesTwo.__init__(self)
PlusFive.__init__(self)
#부모 클래스의 순서에 따라 초기화
foo = OneWay(5)
print('첫 번째 부모 클래스 순서에 따른 값은 (5*2) + 5 =', foo.value)
첫 번째 부모 클래스 순서에 따른 값은 (5*2) + 5 = 15
순서를 바꿔도 결과가 동일하다는 것은 부모 클래스의 나열한 순서와 부모 클래스의 생성자 호출 순서 불일치
class AnotherWay(MyBaseClass, PlusFive, TimesTwo):
def __init__(self, value):
MyBaseClass.__init__(self, value)
TimesTwo.__init__(self)
PlusFive.__init__(self)
bar = AnotherWay(5)
print('두 번째 부모 클래스 순서에 따른 값은 (5*2) + 5 =', bar.value)
두 번째 부모 클래스 순서에 따른 값은 (5*2) + 5 = 15
"""
파이썬에는 super라는 내장 함수와 표준 메서드 결정 순서(MRO)가 있다.
super를 사용하면 다이아몬드 계층의 공동 상위 크랠스르 한 번만 호출
MRO는 상위 클래스를 초기화하는 순서 정의
C3 선형화라는 알고리즘 사용
다이아몬드의 정점에 있는 MyBaseClass__init__는 단 한 번만 실행된다.
다른 부모 클래스의 생성자는 class문에 지정된 순서로 호출
"""
class TimesSevenCorrect(MyBaseClass):
def __init__(self, value):
super().__init__(value)
self.value *= 7
class PlusNineCorrect(MyBaseClass):
def __init__(self, value):
super().__init__(value)
self.value += 9
class GoodWay(TimesSevenCorrect, PlusNineCorrect):
def __init__(self, value):
super().__init__(value)
foo = GoodWay(5)
print('7*(5+9)=98이 나와야하고 실제로도', foo.value)
7*(5+9)=98이 나와야하고 실제로도 98
mro_str = '\n'.join(repr(cls) for cls in GoodWay.mro())
print(mro_str)
<class 'main.GoodWay'>
<class 'main.TimesSevenCorrect'>
<class 'main.PlusNineCorrect'>
<class 'main.MyBaseClass'>
<class 'object'>
#object 인스턴스를 초기할 때 두 파라미터를 지정할 필요가 없다.
class ExplicitTrisect(MyBaseClass):
def __init__(self, value):
super(ExplicitTrisect, self).__init__(value)
self.value /= 3
class AutomaticTrisect(MyBaseClass):
def __init__(self, value):
super(__class__, self).__init__(value)
self.value /=3
class ImplicitTrisect(MyBaseClass):
def __init__(self, value):
super().__init__(value)
self.value /= 3
assert ExplicitTrisect(9).value ==3
assert AutomaticTrisect(9).value ==3
assert ImplicitTrisect(9).value ==3
파이썬은 표준 메서드 결정 순서(MRO)를 활용해서 상위 클래스 초기화 순서와 다이아몬드 상속 문제 해결
부모 클래스를 초기화할 때는 super내장 함수를 아무 인자없이 호촐하라
super에 파라미터 지정하는 유일한 경우
자식 클래스에서 상위 클래스의 특정 기능에 접근