Comprendre les décorateurs (decorators) en Python
Les décorateurs en Python sont un moyen puissant et flexible de modifier le comportement d'une fonction ou d'une classe. Ils sont une forme de fonctions d'ordre supérieur, ce qui signifie qu'ils peuvent prendre une fonction en argument, lui ajouter une certaine fonctionnalité, puis renvoyer une nouvelle fonction. Cela vous permet d'étendre la fonctionnalité d'une fonction sans modifier sa logique principale.
Qu'est-ce que les décorateurs ?
Les décorateurs sont un moyen d'envelopper une fonction avec une autre fonction. La fonction interne, connue sous le nom de « décorateur », effectue généralement un traitement ou une fonctionnalité supplémentaire avant ou après l'appel de la fonction d'origine. Cela peut être utile pour des tâches telles que la journalisation (logging), la mise en cache (caching), l'authentification, etc.
Les décorateurs en Python sont définis à l'aide du symbole @
, suivi du nom de la fonction décorateur, placé juste avant la définition de la fonction. Lorsqu'une fonction est décorée, la fonction décorateur est appelée avec la fonction d'origine en argument, et le résultat de la fonction décorateur est utilisé comme nouvelle fonction.
Voici un exemple simple d'un décorateur qui enregistre les arguments passés à une fonction :
def log_args(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with args={args} and kwargs={kwargs}")
return func(*args, **kwargs)
return wrapper
@log_args
def add_numbers(a, b):
return a + b
result = add_numbers(2, 3)
print(result)
Cela affichera :
Calling add_numbers with args=(2, 3) and kwargs={}
5
Composition de décorateurs
Les décorateurs peuvent être composés, ce qui vous permet d'appliquer plusieurs décorateurs à une seule fonction. Les décorateurs sont appliqués de bas en haut, le décorateur le plus interne étant appliqué en premier.
def uppercase(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
return result.upper()
return wrapper
@uppercase
@log_args
def greet(name):
return f"Hello, {name}!"
print(greet("LabEx"))
Cela affichera :
Calling greet with args=('LabEx',) and kwargs={}
HELLO, LABEX!
Comprendre la syntaxe *args
et **kwargs
La syntaxe *args
et **kwargs
est utilisée dans les décorateurs pour permettre au décorateur de gérer des fonctions avec un nombre quelconque d'arguments positionnels et d'arguments clé-valeur. Le *args
collecte tous les arguments positionnels dans un tuple, tandis que le **kwargs
collecte tous les arguments clé-valeur dans un dictionnaire.
Cette flexibilité garantit que le décorateur peut être appliqué à une grande variété de fonctions, indépendamment de leurs signatures d'arguments.