En Python, les décorateurs sont devenus une partie du langage depuis la version 2.4, permettant de modifier le comportement des fonctions et des classes. Les décorateurs pour les paramètres de fonction sont un motif plus complexe, qui est réalisé manuellement, car il n'y a pas de prise en charge syntaxique directe pour de tels décorateurs dans le langage. Cependant, grâce aux annotations et à la méta-programmation, leur fonctionnalité peut être réalisée.
Les décorateurs ordinaires agissent sur l'ensemble de la fonction ou de la méthode. Parfois, il est nécessaire de valider, de journaliser ou de modifier uniquement des paramètres spécifiques de la fonction à un certain niveau d'abstraction. Par exemple, vérifier le type d'argument, transformer la valeur du paramètre ou imposer des restrictions sur l'entrée.
Les décorateurs de paramètres de fonction sont créés en tant que métadonnées (par exemple, via des annotations de type) et sont traités dans un décorateur englobant externe. L'essence du motif est de conserver les informations nécessaires sur les paramètres, puis le décorateur "fonctionnel" les utilise pour traiter les valeurs lors de l'appel de la fonction.
Exemple de code :
import inspect from functools import wraps def positive_param(fn): """Annotation pour vérifier obligatoirement que l'argument est positif.""" fn._positive = True return fn # Décorateur externe complet def validate_decorator(func): spec = inspect.getfullargspec(func) @wraps(func) def wrapper(*args, **kwargs): bound_args = inspect.signature(func).bind(*args, **kwargs) for name, value in bound_args.arguments.items(): param = func.__annotations__.get(name, None) if getattr(param, '_positive', False) and value <= 0: raise ValueError(f"L'argument {name} doit être positif") return func(*args, **kwargs) return wrapper @validate_decorator def deposit(amount: positive_param): print(f"Déposé {amount}") deposit(10) # OK deposit(-5) # ValueError
Caractéristiques clés :
Comment les décorateurs de paramètres diffèrent-ils des décorateurs de fonction standard ?
Un décorateur standard enveloppe l'ensemble de la fonction, indépendamment des paramètres. Un décorateur de paramètre se concentre sur un argument spécifique et s'applique uniquement à celui-ci, ce qui nécessite des techniques de traitement et d'analyse de signature non standards.
Les décorateurs de paramètres peuvent-ils être implémentés via la syntaxe @ en Python, comme cela se fait en TypeScript ou C# ?
Non, en Python, la syntaxe des décorateurs via @ s'applique uniquement aux fonctions et aux classes, mais pas aux paramètres individuels de la fonction. Pour les paramètres, on utilise des annotations, puis on traite les annotations lors de l'enveloppement de la fonction.
Peut-on appliquer automatiquement des décorateurs aux paramètres des arguments de la fonction sans annotation explicite ?
Non, Python n'applique pas automatiquement des décorateurs aux paramètres, mais il est possible de réaliser un mécanisme personnalisé, par exemple via une fabrique de décorateurs sur mesure, qui analysera la signature de la fonction et remplacera les valeurs des paramètres lors de l'appel.
Le développeur est convaincu qu'il est possible d'utiliser @ sur le paramètre, comme dans d'autres langages, et écrit :
def f(@validate_positive x): ...
Avantages :
Inconvénients :
Le développeur utilise une annotation et un décorateur externe, comme dans l'exemple ci-dessus, et traite les paramètres via la signature et les annotations :
Avantages :
Inconvénients :