본문 바로가기
Python/Study

[Overriding] 오버라이딩을 이용한 코드 수정

by beeny-ds 2022. 8. 2.

들어가는 글

 Python 패키지를 사용하다보면 본인이 원하는 방식으로 class를 수정하고 싶을 때가 있다. 보통 pypi에서 직접 패키지를 수정하지만 git으로 내 패키지를 관리 한다면 dependency가 있는 다른 패키지를 수정하여 사용하고 싶을 때 pypi에서 수정하는 건 비효율 적이다. (다수의 wheel 파일 생성 및 관리 필요하기 때문)
 본 포스팅에서는 오버라이딩을 이용한 class 수정으로 위와 같은 니즈가 있을 때 어떻게 효율적으로 수정할 수 있는지, 그때의 이점은 무엇인지 알아보도록 하자.

 

상속(Inheritance)

상속이란 '뒤를 이음', '물려 받다' 라는 뜻으로, class에도 이런 개념을 적용할 수 있다.

어떤 class를 만들 때 다른 class의 기능을 그대로 가져올 수 있는 개념인데
이 때, 물려 주는 class를 부모 class(Super class), 물려 받는 class를 자식 class(Sub class) 라고 한다.

즉, class 상속은 중복된 메서드를 재정의할 필요가 없다는 장점이 있다. 또한, 기존 class에서 일부 기능을 추가하거나 변경함으로써 새로운 class를 정의할 수 있기 때문에 효율적인 코드 작성이 가능하다.

클래스를 상속은 자식 class 이름 뒤의 괄호 안에 부모 class의 이름을 입력하면 된다. 아래 예시 코드를 참고하자.
class Super_cl:    # 부모 class 지정
    def __init__(self, name):
        self.name = name
        
    def age(self, age):
        print(f"{self.name}'s' age is {age}")
        
    def like_food(self, food):
        print(f"{self.name} likes {food}")
        

class Sub_cl(Super_cl):    # 자식 class 지정 시 부모 class 상속
    def __init__(self, name): 
    	self.name = name
        print(f"my name is {self.name}")
        
        
parent = Super_cl(name = 'Beeny')
parent.age(age = 100)
parent.like_food(food = '국밥')

chid = Sub_cl(name = 'Beeny')
chid.age(age = 100)
chid.like_food(food = '순대국')

출력 결과는 아래와 같이 나온다.

더보기

>>> Beeny's' age is 100
>>> Beeny likes 국밥

>>> my name is Beeny
>>> Beeny's' age is 100
>>> Beeny likes 순대국

 

위의 예시와 같이 상속만 해주면 부모 class 의 메소드를 사용할 수 있다.
이제 본 포스팅의 메인 주제인 메소드 오버라이딩을 살펴보자.


 

메소드 오버라이딩(Overriding)

메소드 오버라이딩은 상속의 개념 중 하나라고 생각하면 된다. 오버라이딩은 자식 class가 부모 class 들 중 하나에 의해 이미 제공된 메소드를 특정한 형태로 구현하는 것이다.class를 만들다 보면 메소드의 이름은 같지만 기능을 다르게 해야 할 때가 있는데, 이 때 메소드 오버라이딩 개념을 적용하면 된다. 아래 예제를 살펴보면 쉽게 파악할 수 있을 것이다.

class Super_cl:    # 부모 class 지정
    def __init__(self, name):
        self.name = name
        
    def age(self, age):
        print(f"{self.name}'s' age is {age}")
        
    def like_food(self, food):
        print(f"{self.name} likes {food}")
        

class Sub_cl(Super_cl):    # 자식 class 지정
    def like_food(self, food, drink):    # 부모 class 메소드 구조 변경
        print(f"{self.name} likes {food} and {drink}")
        
        
parent = Super_cl(name = 'Beeny')
parent.age(age = 100)
parent.like_food(food = '국밥')

chid = Sub_cl(name = 'Beeny')
chid.age(age = 100)
chid.like_food(food = '순대국', drink = '이온 음료')

자식 class는 부모 class를 상속했으므로 __init__ 메소드를 재정의 할 필요 없다. (만약 인자를 추가가 필요하지 않다면)
출력 결과는 아래와 같이 나온다.

더보기

>>> Beeny's' age is 100
>>> Beeny likes 국밥

>>> Beeny's' age is 100
>>> Beeny likes 순대국 and 이온 음료

 

자식 class에서 오버라이딩한 메소드는 like_food 메소드이므로 age 메소드의 결과는 부모 class와 같은 결과를 보인다.
like_food 메소드의 결과는 두 class 간 다른 결과를 보인다. 오버라이딩한 메소드이기 때문이다.

이와 같이 오버라이딩을 이용하면 기존에 있는 class를 활용하여 효율적인 개발을 할 수 있다. 새로 구성하고자 하는 class의 코드 구조가 단순화될 뿐만 아니라 문제가 있는 코드를 빠르게 찾아 고칠 수 있다는 장점을 가지고 있다.

단, 주의할 점은 메소드 오버라이딩을 활용하면 부모 class에서 정의한 메소드의 기능을 자식 class에서 재활용이 불가능 하다는 점이다. 이러한 단점을 보완하기 위해 슈퍼 함수(super)가 등장한다. 슈퍼 함수에 관한 설명은 다음 포스팅에서 확인하길 바란다.

 

마무리 글

필자는 모델 배포를 위해 몇 개의 패키지를 사용하면서 오버라이딩 니즈가 생겼다. dependency 패키지를 건드리지 않으면서 dependency 패키지에서 일부 class를 수정하여 사용해야 했기 때문이다. 모델 배포를 위해 wheel 파일로 전달하는 과정이 필요했기에 여러 가지를 고려하여 오버라이딩을 이용한 class 메소드 수정 방식을 택하여 개발을 했다.

오버라이딩을 사용하여 개발하기 전 추천하는 Check list 이다.

  1. 부모 class로 사용하고자 하는 메서드를 얼마나 이해하고 있는가
  2. 수정하고자 하는 메서드는 어디이고 어떻게 수정하길 원하는가
  3. 부모 class로 사용하고자 하는 패키지의 버전은 무엇인가
    • 버전 업데이트로 부모 class가 수정될 예정인가
    • 배포를 위한 버전 관리를 하고 있는가
  4. PEP8(파이썬 코드의 작성규칙) 에 따라 코드 개발을 했는가

 

다음 포스팅에서는 슈퍼 함수(super)에 대해 알아보자.

반응형

댓글