들어가는 글
지난 포스팅에서는 상속(Inheritance)과 오버라이딩(Overriding)에 대해 알아봤었다. 관련된 링크는 아래 글을 참고하길 바란다.
본 포스팅에서는 객체 지향형 프로그램 언어에서 상속 시 많이 사용하는 Super 함수에 대해 알아보도록 하자.
https://beeny-ds.tistory.com/23
Super 함수
Super 명령어는 상속 관계에서 상속의 대상인 부모 class를 호출하는 함수이다.
super().__init__() 이라는 코드가 부모 class의 속성 및 메소드를 자동으로 불러와 해당 class에서도 사용이 가능하도록 해준다.
super(하위 class, self).__init__(arguments)
위와 같이 super() 괄호 안에 아무것도 넣어주지 않아도 된다.(단, python 3.x version 의 경우만..)
.__init__() 괄호 안에는 부모 class 의 arguments 를 전부 넣어줘야 한다.
super 함수는 __init__ 메소드 뿐만 아니라 다른 메소드도 호출하여 사용할 수 있다.
만약 def who_name(self): 이라는 메소드가 있다면 super().who_name() 으로 호출하여 사용하면 된다.
예시를 통해 super().__init__() 을 자세히 살펴보자.
class Super_cl: # 부모 class 지정
def __init__(self, name: str, kick_name: str):
self.name = name
self.kick_name = kick_name
info = f"{name}'s kick name is {kick_name}"
print(info)
self.info = info
def age(self, age):
print(f"{self.name}'s' age is {age}")
def like_food(self, food):
print(f"{self.name} likes {food}")
print(f"{self.name}'s info: \n name: {self.kick_name} \n favorit food: {food}")
class Sub_cl(Super_cl): # 자식 class 지정
def __init__(self, name, kick_name):
super(Sub_cl, self).__init__(name, kick_name)
# super().__init__(name, kick_name) 이것도 가능
def like_food(self, food, drink): # 부모 class 메소드 구조 변경
print(f"{self.name} likes {food} and {drink}")
print(self.info)
parent = Super_cl(name = 'Beeny', kick_name = 'talent')
parent.age(age = 100)
parent.like_food(food = '국밥')
chid = Sub_cl(name = 'Beeny', kick_name = 'talent')
chid.age(age = 100)
chid.like_food(food = '순대국', drink = '이온 음료')
출력 결과는 아래와 같이 나온다.
>>> Beeny's kick name is talent
>>> Beeny's' age is 100
>>> Beeny likes 국밥
>>> Beeny's info:
name: talent
favorit food: 국밥
>>> Beeny's kick name is talent
>>> Beeny's' age is 100
>>> Beeny likes 순대국 and 이온 음료
>>> Beeny's kick name is talent
부모 class 의 __init__ 메소드에서 만들어준 'info' 가 자식 class 에서도 'print' 된 것을 볼 수 있다.
자식 class 에서 오버라이딩을 통해 like_food 메소드를 다르게 정의해줬지만 super 함수로 인해 'self.info' 를 like_food 메소드에서 사용해준 것을 볼 수 있다. 만약 super().__init__() 을 사용하지 않았다면 자식 class 의 like_food 메소드에서는 'self.info' 를 사용할 수 없다. 부모 class 의 __init__ 메소드에서 정의한 'self.info' 정보를 가져올 수 없기 때문이다.
그렇다면 super 함수를 사용할 때 주의할 점은 무엇일까?
Super 함수 사용 시 주의할 점
Super 함수를 사용하며 필자가 경험한 실수를 공유하고자 한다.
- super().__init__() 의 괄호 안 부모 class 의 arguments 를 지정할 때 default 값은 설정하지 말도록 하자. (설정한 default 값이 부모 class 의 __init__ 메소드에서 연산된다.)
- 자식 class 에서 __init__ 메소드를 만들 때 부모 class 의 __init__ 메소드에 해당하는 arguments 값들을 지정해야 한다. (만약 지정하지 않으면 인자가 없다는 에러를 만난다.)
필자가 코딩하는 방식은 아래와 같다.
class Super_cl: # 부모 class 지정
def __init__(self,
name: str,
kick_name: str):
self.name = name
self.kick_name = kick_name
info = f"{name}'s kick name is {kick_name}"
print(info)
self.info = info
def age(self, age):
print(f"{self.name}'s' age is {age}")
def like_food(self, food):
print(f"{self.name} likes {food}")
print(f"{self.name}'s info: \n name: {self.kick_name} \n favorit food: {food}")
class Sub_cl(Super_cl): # 자식 class 지정
def __init__(self,
name: str, # 부모 class의 인자와 같은 형태로 통일
kick_name: str): # 부모 class의 인자와 같은 형태로 통일
super(Sub_cl, self).__init__(name = name, # 자식 class의 인자를 받도록 설정
kick_name = kick_name) # 자식 class의 인자를 받도록 설정
def like_food(self, food, drink): # 부모 class 메소드 구조 변경
print(f"{self.name} likes {food} and {drink}")
print(self.info)
자식 class 의 __init__ 메서드에 들어가는 인자는 부모 class 의 __init__ 메서드와 완전 통일시킨다.
super().__init__() 함수 안에 들어가는 인자는 어떤 값이 들어가는지 명시한다.
필자가 위와 같은 방식으로 개발하는 이유는 시간이 지나 예전에 개발하던 코드를 잊어버리고 다시 확인할 때를 위해서이다. 개발을 하다보면 이런 일이 생각보다 많은데 위와 같은 방식으로 구성해야 다시 코드를 확인할 때 편하기 때문이다. 물론 필자의 방식이 좋은 방식이다 라고 말하기엔 애매하다. PEP8 과 같은 규칙에 맞춰 개발하는 방법이 best다.
마무리 글
super 함수는 사용하기에 따라 유용할 수도 있고 오히려 불편할 수도 있다. 상속하고자 하는 class를 얼마나 이해했는지, 내부 기능(ex. 메소드)에 대해 얼마나 알고 있는지에 따라 효율성이 다르다고 생각한다. 때문에 개발을 하기 전 나의 코드를 어떻게 구성할지 명확히 설계한 뒤 시작하길 바란다.
'Python > Study' 카테고리의 다른 글
[창시모] unittest in python (0) | 2022.09.05 |
---|---|
[class 기능 정리] 코딩을 깔끔하게 해주는 기능 (0) | 2022.08.12 |
[Overriding] 오버라이딩을 이용한 코드 수정 (0) | 2022.08.02 |
[소개] ONNX 란? (0) | 2022.07.27 |
[Package] 파이썬 코드 패키지화 → setup.py (0) | 2022.07.11 |
댓글