날짜: 2024-12-02
파이썬에서 함수 오버로딩과 singledispatch
데코레이터는 서로 관련이 있으면서도, 다른 맥락에서 이해할 수 있습니다. 여기서는 두 개념을 비교하고, singledispatch
데코레이터를 활용하여 파이썬에서 함수 오버로딩을 구현하는 방법을 설명하겠습니다.
함수 오버로딩은 같은 이름을 가진 함수가 매개변수의 개수나 타입에 따라 다르게 동작하는 기능을 말합니다. C++, Java와 같은 언어에서는 기본적으로 함수 오버로딩을 지원합니다.
int add(int a, int b) {
return a + b;
}
float add(float a, float b) {
return a + b;
}
위 예시에서 함수 이름은 같지만, 매개변수의 타입에 따라 다른 구현이 호출됩니다.
파이썬은 함수 오버로딩을 기본적으로 지원하지 않습니다.
파이썬은 동적 타이핑(dynamic typing)을 기반으로 하기 때문에, 함수 호출 시점에 매개변수의 타입을 체크하여 서로 다른 구현을 선택하는 기능이 기본적으로 없습니다. 동일한 이름의 함수를 두 번 이상 정의하면, 이전 정의가 덮어쓰여집니다.
예제: 덮어쓰기
def add(a, b):
return a + b
def add(a, b, c):
return a + b + c
print(add(1, 2)) # TypeError: add() missing 1 required positional argument
singledispatch
데코레이터를 활용한 함수 오버로딩파이썬에서는 functools
모듈의 singledispatch
데코레이터를 사용하여 함수 오버로딩과 유사한 동작을 구현할 수 있습니다. singledispatch
는 매개변수의 타입에 따라 다른 구현을 선택하는 제네릭 함수(generic function)를 제공합니다.
singledispatch
의 기본 개념@singledispatch
로 데코레이트합니다.@<함수명>.register(타입)
으로 정의합니다.singledispatch
사용법from functools import singledispatch
@singledispatch
def process(data):
raise NotImplementedError("Unsupported type")
@process.register(int)
def _(data):
return f"Processing integer: {data}"
@process.register(str)
def _(data):
return f"Processing string: {data}"
@process.register(list)
def _(data):
return f"Processing list of length {len(data)}"
# 함수 호출
print(process(42)) # 출력: Processing integer: 42
print(process("hello")) # 출력: Processing string: hello
print(process([1, 2, 3])) # 출력: Processing list of length 3
singledispatch
사용파이썬 3.8부터는 singledispatchmethod
를 사용하여 클래스 메서드에서도 함수 오버로딩을 구현할 수 있습니다.
from functools import singledispatchmethod
class Processor:
@singledispatchmethod
def process(self, data):
raise NotImplementedError("Unsupported type")
@process.register(int)
def _(self, data):
return f"Processing integer: {data}"
@process.register(str)
def _(self, data):
return f"Processing string: {data}"
processor = Processor()
print(processor.process(42)) # 출력: Processing integer: 42
print(processor.process("hello")) # 출력: Processing string: hello
singledispatch
의 장점과 한계singledispatch
는 함수의 첫 번째 매개변수의 타입만을 기준으로 동작을 결정합니다.가장 간단한 방법은 매개변수의 타입을 확인하고 적절한 로직을 선택하는 것입니다.
def process(data):
if isinstance(data, int):
return f"Processing integer: {data}"
elif isinstance(data, str):
return f"Processing string: {data}"
elif isinstance(data, list):
return f"Processing list of length {len(data)}"
else:
raise NotImplementedError("Unsupported type")
singledispatch
를 확장하여 다중 매개변수를 처리하는 디스패처를 구현할 수도 있습니다.
singledispatch
데코레이터를 사용하면 타입별로 다른 동작을 수행하는 함수를 쉽게 작성할 수 있습니다.singledispatch
는 첫 번째 매개변수의 타입을 기준으로 동작하며, 간결하고 확장 가능한 코드를 작성하는 데 유용합니다.