Maison > Article > développement back-end > Surcharge de fonctions en Python
La surcharge de fonctions fait référence à la possibilité de définir plusieurs fonctions avec le même nom mais des signatures différentes, ce qui signifie qu'elles ont des nombres ou des types de paramètres différents. La version correcte de la fonction est choisie automatiquement par le compilateur ou l'interpréteur, en fonction du nombre et du type d'arguments passés lors de l'appel de la fonction.
Des langages comme Java et C++ prennent en charge cette fonctionnalité de manière native.
Bien que Python ne prenne pas en charge la surcharge de fonctions de manière native puisqu'il s'agit d'un langage typé dynamiquement, il est possible de l'implémenter à l'aide de divers modules et utilitaires.
C'est mon implémentation de la surcharge.
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
La classe OverloadNamespace est un appelable qui agit comme un intermédiaire entre le nom de la fonction et la signature de l'appel. Les arguments sont transmis à la méthode __call__ dunder qui fait correspondre les types de données fournis avec les tuples de types stockés dans le dictionnaire des surcharges. La signature correspondante est renvoyée et est appelée avec les arguments/kwargs fournis. Si aucune signature correspondante n'est trouvée, la fonction de secours est appelée.
Cette classe n'est pas destinée à être utilisée manuellement, elle est utilisée par des décorateurs qui modifient la fonction et renvoient une instance de la classe OverloadNamespace en utilisant le même nom que le nom fourni par la fonction.
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
Le décorateur de surcharge vérifie les types d'arguments à l'aide de la valeur du décorateur ou des indices de type et renvoie la classe d'espace de noms.
Exemple d'utilisation
# 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
Ceci n'est qu'une idée de base et fonctionne pour les types fixes non syndiqués.
Les fonctions de secours sont utilisées comme fonction à appeler lorsqu'aucun modèle d'argument ne correspond au modèle d'appel.
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
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!