파이썬 메소드 오버라이딩/메소드 오버로딩// 인프런 파이썬 강의 Level 3 (2-2)
2022. 1. 14. 22:39
- 인프런의 '프로그래밍 시작하기:파이썬(Level3)'의 내용을 따라가면서 정리
- (2-2)에서는 다음에 관하여 다룸
- 메소드 오버라이딩
- 메소드 오버로딩
1.메소드 오버라이딩
- 클래스가 가진 메소드들을 다른(자식) 클래스에 상속(전달)해 주는 것
- 상속해주는 클래스를 부모클래스 또는 슈퍼클래스라고 부름
- 상속받는 클래스를 자식클래스 혹은 서브클래스라고 부름
- 쓰는 이유?
- 메소드의 재정의 후 사용가능 > 다형성(다양한 방식으로 동작)과 같은 확장성 증가
- 가독성 증가, 오류가능성 감소, 메소드 이름 절약
메소드 오버라이딩 예제
- 부모클래스를 만들고, 자식클래스에 상속시켰음 (클래스의 인수로 다른 클래스를 받으면 상속이 된다)
- 기본적으로 모든 메소드는 그대로 상속이 되나, 동일한 이름이 자식클래스에 있을 경우 자식클래스의 메소드를 따라간다.
class ParentEx1():
def __init__(self):
self.value = 5
def get_value(self):
return self.value
def get_mul_value(self):
return self.value * 5
class ChildEx1(ParentEx1):#메소드 오버라이딩. 부모의 모든 변수를 다 가져옴
def get_mul_value(self):
return self.value * 10
#인스턴스화
p1 = ParentEx1()
c1 = ChildEx1()
###실행###
print("-----get_value-----")
print("p1 :",p1.get_value())
print("c1 :",c1.get_value())
print("-----get_mul_value-----")
print("p1 :",p1.get_mul_value())
print("c1 :",c1.get_mul_value())
- get_value 메소드는 부모클래스의 메소드를 그대로 상속받음
- get_mul_value는 자식클래스에 동일한 이름을 가진 메소드가 있으므로 상속되지 않음. 자식클래스의 메소드가 사용됨(그래서 값이 다르게 출력됨)
dir 과 __dict__
- __dir__은 사용할 수 있는 모든 속성들을 보여줌
- __dict__는 네임스페이스에 있는 속성들의 키값:벨류값을 보여줌
- 부모클래스를 상속받는 자식클래스는 부모클래스에 있는 속성들을 사용할 수 있으므로 dir은 동일하게 출력됨
- 근데 __dict__에서 출력되는 네임스페이스에는 차이가 있음
- 이는 자식클래스를 활용해 인스턴스를 만드는 그 시점에 부모클래스로부터 속성을 상속받아서 인스턴스에 전달해주기 때문임
- 즉 어차피 부모클래스로부터 상속받아 사용할 수 있으므로 dir에 나오지만 일단 현재 가지고 있는 것은 아니므로 네임스페이스에 없어서 __dict__에 나오지 않음
# dir
print('Parent dir > ', dir(ParentEx1))
print('Child dir > ', dir(ChildEx1))
print()
# __dict__
print('Parent dict > ', ParentEx1.__dict__)
print('Child dict> ', ChildEx1.__dict__)
#자식클래스는 네임스페이스에 내용이 많이 없음
#인스턴스가 생성될 때 네임스페이스의 속성들까지 상속받는 것이기 때문
- dir은 차이가 없으나, __dict__의 출력값에 차이가 있다
메소드 오버라이딩을 활용한 다형성
- 메소드 오버라이딩의 장점 중 하나는 다형성
- 말이 어려운데, 쉽게 말해서 부모클래스에서 정의한 메소드를 기반으로 다양하게 수정하여 확장시켜나갈 수 있다는 것이다.
- 보통 super()가 활용된다. super()는 부모클래스의 메소드를 호출하여 사용할 수 있다.
- super는 첫번째 인자로 현재 자신이 속한 메소드, 두번째 인자로 인스턴스 객체(보통 self)를 넣어줄 수 있는데, 비워두면 자동으로 알아서 그렇게 채워줌(밑의 예제 참고)
import datetime
class Logger():
def parent_log(self,msg):
print(msg)
class Logger_with_time_detailed(Logger):
def log(self,msg):
now_time = datetime.datetime.now()
message = f'time : {now_time}, msg = {msg}'
super().parent_log(message)
class Logger_with_time_ymd(Logger):
def log(self,msg):
now_time = datetime.datetime.now().strftime('%y-%m-%d')
message = f'time : {now_time}, msg = {msg}'
super(Logger_with_time_ymd,self).parent_log(message)
#super().parent_log(message)로 해도 상관없다
#인스턴스
c1 = Logger_with_time_detailed()
c2 = Logger_with_time_ymd()
#####실행#####
c1.log("hi!")
c2.log("hi!")
- Logger라는 부모클래스와, 부모클래스를 상속받는 자식클래스를 두개 작성
- 두 자식클래스의 메소드들 모두, super()를 활용하여 부모클래스의 parent_log 메소드를 사용해 message를 출력한다(자식클래스의 메소드에는 print가 없음!!)
- 이렇게 상위클래스의 메소드를 가져와서 입맛에 맞게 수정할 수 있는게 메소드 오버라이딩의 장점인 다형성(확장성)임
2.메소드 오버로딩
- 메소드 오버로딩은 '하나의 메소드가 매개변수에 따라 다른 기능으로 동작하게 함.' 즉 하나의 이름으로 상황에 따라 다르게 동작하는 메소드를 만드는 것임
- 메소드 오버라이딩은 '클래스의 상속시에 상속받은 메소드를 자식클래스에서 수정하는 것'
- 메소드 오버로딩은 '하나의 메소드에게 다형성을 부여하는 것'(메소드와 매개변수사이의 일임)
메소드 오버로딩 - 직접구현
- 과거에는 datatype이나 매개변수의 개수와 같은 것을 메소드의 인자로 함께 줘서 datatype의 종류나 개수에 따라 다른 작업이 수행되는 방식을 사용했었음
- 이런식으로 구현되어있는 코드가 여전히 많음
class SampleA():
def add(self,datatype,*args):
if datatype == 'int':
return sum(args)
if datatype == 'str':
return ''.join([x for x in args])
#인스턴스
a = SampleA()
#####실행#####
print(a.add('int',1,2,3,4)) #10 출력
print(a.add('str',"a","p","p","l","e")) #apple 출력
메소드 오버로딩 - multipled dispatch
- 최근에 multipled dispatch라는 기능이 추가되면서 , 얘를 활용해서 메소드 오버로딩을 할 수 있음
- 동일한 이름을 가진 메소드에 자료형의 종류와 개수에 대한 정보를 데코레이터해줌
- 메소드를 호출할 때, 인자로 받는 자료형의 종류 및 개수와 데코레이터된 정보가 일치하는 메소드가 호출됨
from multipledispatch import dispatch
class SampleB():
@dispatch(int,int,int)
def product(x,y,z):
print("int!")
return x * y * z
@dispatch(float,float,float)
def product(x,y,z):
print("float!")
return x + y + z
#인스턴스
b = SampleB()
#####출력#####
print(b.product(4,5,6))
print(b.product(4.0,5.0,6.0))
- @dispatch를 활용하여, int자료형들이 인자로 들어올 경우 서로 곱해지는 product 메소드가, float자료형들이 인자로 들어올 경우 서로 더해주는 product 메소드가 호출되도록 하였음
'프로그래밍 언어 > python' 카테고리의 다른 글
파이썬 descriptor// 인프런 파이썬 강의 Level 3 (3-2) (0) | 2022.01.18 |
---|---|
파이썬 메타클래스(metaclass)// 인프런 파이썬 강의 Level 3 (3-1) (0) | 2022.01.16 |
변수의 종류(public,protected,private), getter &setter , property// 인프런 파이썬 강의 Level 3 (2-1) (0) | 2022.01.14 |
파이썬 context manager 구현 + 에러// 인프런 파이썬 강의 Level 3 (1-3) (0) | 2022.01.13 |
노션이동 완료 // 파이썬 shallow copy & deep copy (얕은 복사, 깊은 복사) // 인프런 파이썬 강의 Level 3 (1-2) (0) | 2022.01.12 |