super로 부모 클래스 초기화 하기

7804 단어 supersuper

부모 클래스를 상속 받는 자식 클래스가 있을 경우 super 내장 함수를 이용해 다이아몬드 계층의 공통 상위 클래스를 단 한 번만 호출하도록 할 수 있다.

다이아몬드 계층이란?

  • 여러 부모 클래스를 상속 받을 때 해당 부모 클래스가 공통으로 상속 받는 부모 클래스가 있다면 이 때 클래스들의 계층은 다이아몬드 모양이 되어 이를 다이아몬드 계층이라 한다.

아래의 코드를 이용하면 다이아몬드 모양의 클래스 구조를 다시 만드는 대신 super를 사용해 부모 클래스를 초기화 한다.
그러면 다이아몬드의 정점에 있는 MyBaseClass에 도달했을 때 MyBaseClass.__init__이 한 번만 호출 되어 중간에 오버라이딩 되면서 생기는 문제가 사라진다.


오버라이딩 되며 생기는 문제

(예시) 아래의 예시는 파이썬 코딩의 기술(개정 2판, 브렛 슬라킨 저)에서 가져온 것입니다.

# 부모 클래스
class MyBaseClass:
	def __init__(self, value):
    	self.value = value
        
# 자식 클래스
class TimesSeven(MyBaseClass):
	def __init__(self, value):
    	MyBaseClass.__init__(self, value)
        self.value *= 7

# 자식 클래스
class PlusNine(MyBaseClass):
	def __init__(self, value):
    	MyBaseClass.__init__(self, value)
        self.value += 9

아래와 같이, TimesSeven과 PlusNine을 모두 상속하는 자식 클래스를 정의하면 MyBaseClass가 다이아몬드 계층의 가장 상위에 있게 된다.
이 경우, 두 번째 부모 클래스의 생성자인 PlusNine.__init__(self, value)를 호출할 때 MyBaseClass.init(self, value)가 다시 호출되면서 self.value가 5로 돌아간다.
이는 예상한 결과가 아니기 때문에 버그를 잡기 힘들 수 있다.

class ThisWay(TimesSeven, PlusNine):
	def __init__(self, value):
		TimesSeven.__init__(self, value)
		PlusNine.__init__(self, value)
        
print(ThisWay(5).value)  # (5 * 7) + 9 = 44가 아닌 14가 나옴

따라서, 아래와 같이 super를 사용해서 다이아몬드 계층의 공통 상위 클래스를 한 번만 호출하도록 보장할 수 있다.

class TimesSeven(MyBaseClass):
	def __init__(self, value):
    	super().__init__(self, value)
        self.value *= 7

class PlusNine(MyBaseClass):
	def __init__(self, value):
    	super().__init__(self, value)
        self.value += 9

# TimesSeven과 PlusNine을 상속 받은 클래스
class GoodWay(TimesSeven, PlusNine):
	def __init__(self, value):
		super().__init__(self, value)

이제 MyBaseClass.__init__이 한 번만 호출되어 오버라이딩으로 인한 문제점은 발생하지 않는다.

조금 더 분석해 보면,

  • 상속 다이아몬드의 정점에 도달시 각각의 초기화 메서드는 각 클래스의 __init__이 호출된 순서의 역순으로 작업한다(호출은 역순으로 일어난다).
    - 즉, <class 'object'>, <class 'main.MyBaseClass'>, <class 'main.PlusNineCorrect'>, <class 'main.TimesSevenCorrect'>, <class 'main.GoodWay'> 순으로 작업이 이루어지는 것이다.

좋은 웹페이지 즐겨찾기