함수 오버로드는 이름은 같지만 시그니처가 다른 여러 함수를 정의하는 기능을 의미합니다. 즉, 매개변수의 수나 유형이 다릅니다. 함수 호출 중에 전달된 인수의 수와 유형에 따라 컴파일러나 해석기가 자동으로 올바른 버전의 함수를 선택합니다.
Java 및 C++와 같은 언어는 기본적으로 이 기능을 지원합니다.
파이썬은 동적 유형 언어이기 때문에 기본적으로 함수 오버로딩을 지원하지 않지만, 다양한 모듈과 유틸리티를 사용하여 동일하게 구현하는 것은 가능합니다.
이것은 오버로딩을 구현한 것입니다.
from __future__ import annotations import inspect import typing bin: dict[str, OverloadNamespace] = {} class OverloadNamespace: overloads: dict[tuple[type, ...], typing.Callable[..., typing.Any]] fallback: typing.Callable[..., typing.Any] def __init__(self, name: str) -> None: self.overloads = {} self.fallback = self._fallback bin[name] = self def __call__(self, *args: typing.Any, **kwds: typing.Any) -> typing.Any: types = [type(arg) for arg in args] types.extend([type(kwrg) for kwrg in kwds]) try: return self.overloads[tuple(types)](*args, **kwds) except KeyError: return self.fallback(*args, **kwds) @staticmethod def _fallback(*_, **__) -> None: raise NotImplementedError
OverloadNamespace 클래스는 함수 이름과 호출 서명 사이의 매개체 역할을 하는 호출 가능 항목입니다. 인수는 제공된 데이터 유형을 오버로드 사전에 저장된 유형 튜플과 일치시키는 __call__ dunder 메소드로 전달됩니다. 일치하는 서명이 반환되고 제공된 args/kwargs를 사용하여 호출됩니다. 일치하는 서명이 없으면 fallback 함수가 호출됩니다.
이 클래스는 수동으로 사용하기 위한 것이 아니며, 함수를 수정하고 함수에 제공된 이름과 동일한 이름을 사용하여 OverloadNamespace 클래스의 인스턴스를 반환하는 데코레이터에서 활용됩니다.
def overload(*args) -> typing.Callable[..., OverloadNamespace] | OverloadNamespace: """Decorator used to create overloads of functions with same name. Returns a [OverloadNamespace]""" if len(args) == 1 and inspect.isfunction(args[0]): return overload_using_types(args[0]) def inner(func: typing.Callable[..., typing.Any]) -> OverloadNamespace: sig = inspect.signature(func) assert len(args) == len( sig.parameters ), "Number of types and args in function is not same." namespace = ( bin[func.__name__] if bin.get(func.__name__) else OverloadNamespace(func.__name__) ) namespace.overloads[tuple(args)] = func return namespace return inner def overload_using_types(func: typing.Callable[..., typing.Any]) -> OverloadNamespace: args = inspect.signature(func).parameters types = tuple(arg.annotation for arg in args.values()) namespace = ( bin[func.__name__] if bin.get(func.__name__) else OverloadNamespace(func.__name__) ) namespace.overloads[types] = func return namespace
오버로드 데코레이터는 데코레이터 값이나 유형 힌트를 사용하여 인수 유형을 확인하고 네임스페이스 클래스를 반환합니다.
사용예
# types in decorator @overload(int, int) def sum(a, b): return a+b # or as typehints @overload def sum(a: float, b: float): return int(a+b)+1 sum(1,2) # 3 sum(1.23, 2.0) # 4
이것은 단지 기본적인 아이디어이며 비조합 고정 유형에 적용됩니다.
Fallback 함수는 호출 패턴과 일치하는 인수 패턴이 없을 때 호출되는 함수로 사용됩니다.
def fallback( func: typing.Callable[..., typing.Any], ) -> OverloadNamespace: """Fallback function to be called if no overloads match to the provided arguments.""" namespace = ( bin[func.__name__] if bin.get(func.__name__) else OverloadNamespace(func.__name__) ) namespace.fallback = func return namespace @fallback def sum(*args): return sum(args) sum(1,2,3,4) # 10
위 내용은 Python의 함수 오버로딩의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!