오버로딩은 메소드 간 파라미터의 수, 타입, 순서에 의해 동일 이름의 여러 함수를 사용하는 개념이다. 이런 동작이 어떻게 가능한지 알려면 Type Checking에 대해 알고 넘어가야 한다.
유연성 부족, 초기 개발 속도가 느리다 정도가 있는데 사실 정적 타입 검사가 아니더라도 고려해야 하는 부분이라 그렇게 단점은 아니다.
정적 타입 선언과 반대되는 장단점을 가지고 있다. 특히 런타임 에러가 나는건 정말 피곤한 단점이다.
오버라이딩이 부모클래스 상속과 관련된 개념을 다뤘다면 오버로딩은 부모클래스 상관없이 메소드 간 파라미터를 다룬다.
같은 클래스 내에서 동일한 이름의 메소드를 여러 개 가지면서 각각의 메소드가 다른 매개변수를 갖도록 하는 기술이다. 이런 메소드들은 매개변수의 수나 타입에 따라 구별된다.
오버로딩은 정적 타입 체킹의 한 예시다. 컴파일러는 메소드를 호출할 때 제공된 인자에 기반하여 어떤 메소드를 실행할지 결정하게 된다.
하지만 파이썬에서는 기본적으로 오버로딩을 지원하지 않는다! 예를 들어,
class SampleA():
def add(self, x, y):
return x + y
def add(self, x, y, z):
return x + y + z
a = SampleA()
print(a.add(1,2)) # Error!
위 처럼 파이썬에서는 동일 이름의 메소드가 있을 때 가장 마지막으로 선언된 함수로 정의된다.
그래서 기본적으로는 디폴트 인자를 통해 인자 갯수에 대응하거나
def add(a, b, c=0):
return a + b + c
가변 인자를 사용하여 가변 길이의 인자를 받을 수 있다.
def add(*args):
return sum(args)
아니면 데이터 타입을 체킹하고 그에 따른 리턴을 만들 수도 있다.
def add(self, datatype, *args):
if datatype =='int':
return sum(args)
if datatype =='str':
return ''.join([x for x in args])
외부 라이브러리인 multipledispach
를 통해 오버로딩을 편하게 도와주는 데코레이터 dispatch
를 이용하면 가장 편하다.
from multipledispatch import dispatch
class SampleC():
@dispatch(int,int)
def product(x, y):
return x * y
@dispatch(int,int,int)
def product(x, y, z):
return x * y * z
@dispatch(float,float,float)
def product(x, y, z):
return x * y * z
c = SampleC()
print('Ex3 > ', c.product(5, 6)) # 30
print('Ex3 > ', c.product(5, 6, 7)) # 210
print('Ex3 > ', c.product(5.0, 6.0, 7.0)) # 210.0
기존에는 마지막 함수만이 정의되어 에러가 났지만 dispatch
를 통해 같은 함수에 다양한 자료를 받을 수 있게 만들어 준다.
특히 데이터 타입에 의해 함수가 분류되는걸 확인할 수 있다는 점에서 가독성에도 좋다.