[Python] 클래스 다중상속 및 @classmethod Develop Tip

C++, C#, Java 등등의 OO 언어 마다 클래스 상속 개념은 다 있지만,
다중 상속은 되는 언어도 있고 안되는 언어도 있습니다.
(C++은 다중상속은 안되고 friend 개념이 들어있는 것으로 기억하는데
 사용한지 십년도 더 된거 같아 이제는 기억이 가물 가물 하네요)

암튼 파이썬에서도 다중 상속이 잘 됩니다.

class A():
def m(self, *args, **kwargs):
print '%s.m(%s,%s)' % (self.__class__.__name__, args, kwargs)
def mA(self, *args, **kwargs):
print '%s.mA(%s,%s)' % (self.__class__.__name__, args, kwargs)
class B():
def m(self, *args, **kwargs):
print '%s.m(%s,%s)' % (self.__class__.__name__, args, kwargs)
def mB(self, *args, **kwargs):
print '%s.mB(%s,%s)' % (self.__class__.__name__, args, kwargs)
class C(A,B):
def m(self, *args, **kwargs):
print '%s.m(%s,%s)' % (self.__class__.__name__, args, kwargs)

C 클래스는 A와 C 모두에서 상속을 받았고,
m 메소드는 오버로딩 되어 있습니다. 
(파이썬에서는 기냥 namespace 개념으로 해당 공간의 dict를 덮어쓰고
 참조하는 식으로 되어 있습니다)

이제 다음과 같이,

c=C()
c.m(5,6,kw='fgh')
c.mA(5,6,kw='fhi')
c.mB(5,6,kw='hij')

호출을 해 보면,

C.m((5, 6),{'kw': 'fgh'})
C.mA((5, 6),{'kw': 'fhi'})
C.mB((5, 6),{'kw': 'hij'})

와 같이 m은 C 자체 클래스의 메소드가,
또한 mA 메소드는 상속받은 A클래스,
mB 메소드는 상속받은 B클래스의 것이 호출됩니다.

이제는 @staticmethod와 @classmethod의 차이를 살펴보겠습니다.

class A():
S_VAL=1
def m(self, *args, **kwargs):
print '%s.m(%s,%s)' % (self.__class__.__name__, args, kwargs)
def mA(self, *args, **kwargs):
print '%s.mA(%s,%s)' % (self.__class__.__name__, args, kwargs)
@staticmethod
def s():
print '%s.c: S_VAL=%s' % (A.__name__, A.S_VAL)
@classmethod
def c(cls):
print '%s.c: S_VAL=%s' % (cls.__name__, cls.S_VAL)
class B():
S_VAL=2
def m(self, *args, **kwargs):
print '%s.m(%s,%s)' % (self.__class__.__name__, args, kwargs)
def mB(self, *args, **kwargs):
print '%s.mB(%s,%s)' % (self.__class__.__name__, args, kwargs)
class C(A,B):
S_VAL=3
def m(self, *args, **kwargs):
print '%s.m(%s,%s)' % (self.__class__.__name__, args, kwargs)

위와 같이 되어 있는 A클래스에서 s() 라는 @static method가 있습니다.
이것은 첫번째 인자가 self로 시작하는 일반 메소드와는 달리 self로 시작하지 않습니다.
그리고 내용으로는 클래스에 정의되어 있는 S_VAL을 출력합니다.

일반적인 클래스 method라 생각하면 됩니다.

따라서, 

A.s()
C.s()

라고 호출하면,

A.c: S_VAL=1
A.c: S_VAL=1

라고 동일 결과가 나옵니다.

상속은 받았지만 실질적으로 동일 함수가 수행되는 것이지요.

자 이제는 A클래서의 c라는 classmethod를 살펴보겠습니다.
@classmethod 라는 데코레이터를 이용하고,
첫번째 인자로는 cls를 받습니다.
그리고 내용으로는 클래스에 정의되어 있는 S_VAL을 출력합니다.

A.c()
C.c()

라고 호출하면,

A.c: S_VAL=1
C.c: S_VAL=3

라는 결과가 잘 나옵니다.

즉 상속한 클래스의 클래스 내용에 따라 작업을 하고 싶으면 @classmethod를 이용하고,
아무것도 없이 클래스 함수만을 이용한다면 @staticmethod를 호출하는 것이지요...

이것을 어저께야 제대로 이용을 하고는,
'왜 바보같이 이제서야 알았을까나... 그래도 이제야 제대로 알았으니 다행이다'
라고 생각하였답니다.


어느분께는 도움이 되셨기를....

덧글

  • amadeus 2015/06/21 19:22 # 삭제 답글

    정말 많은 도움이 되었습니다. 감사합니다.
  • 지훈현서아빠 2015/06/22 07:43 #

    도움이 되셨다니 저의 보람입니다~~ ^^
  • 버섯 2015/07/28 11:33 # 삭제 답글

    3개의 예제를 같이 비교해보니 쉽게 이해가 됩니다. 감사합니다
  • 지훈현서아빠 2015/07/28 14:04 #

    도움이 되셨다니 저의 보람입니다~ ^^
  • 가우 2015/08/31 20:12 # 삭제 답글

    C++은 다중상속이 되고 자바가 안됨니다^^
  • 지훈현서아빠 2015/09/01 09:57 #

    좋은 지적 감사드립니다. ^^
  • 나그네 2016/01/11 13:08 # 삭제 답글

    이거군요! 좋은 내용 감사합니다.
  • 지훈현서아빠 2016/01/11 15:44 #

    도움이 되셨다니 저의 보람입니다~ ^^
  • maestroj 2017/04/21 12:03 # 삭제 답글

    제가 읽은 글 중에 가장 설명이 잘 되어 있는 글 같습니다. 링크 퍼가겠습니다.
  • 지훈현서아빠 2017/04/24 10:59 #

    도움이 되셨다니 저의 보람입니다~ ^^
  • RL알고리즘 2019/02/28 20:32 # 삭제 답글

    예제가 정말 이해하기 쉽습니다!
  • 지훈현서아빠 2019/03/01 21:54 #

    도움이 되셨다니 저의 보람입니다~ ^^
댓글 입력 영역

구글애드텍스트