Comment créer et utiliser des décorateurs en Python
Apprenez à écrire et appliquer des décorateurs en Python. Maîtrisez les fonctions d'encapsulation, modifiez le comportement, gérez les arguments et préservez les métadonnées avec des encapsulations.
Aperçu
Les décorateurs sont l'une des fonctionnalités syntaxiques les plus élégantes et les plus puissantes de Python, vous permettant de modifier le comportement d'une fonction ou d'une classe sans changer définitivement son code. Ils sont largement utilisés pour des problèmes transversaux tels que la journalisation des temps d'exécution, l'application de l'authentification des utilisateurs, la mise en cache des résultats (mémorisation) et l'audit des points de terminaison de l'API.
Sous le capot, un décorateur est une fonction d'ordre supérieur qui prend une autre fonction comme argument, définit une fonction wrapper imbriquée qui injecte une logique personnalisée et renvoie cette fonction wrapper. Python fournit une syntaxe abrégée claire utilisant le symbole « @ » pour appliquer des décorateurs aux fonctions, les rendant visuellement élégantes.
Lorsque vous écrivez des décorateurs, vous souhaiterez généralement que la fonction décorée prenne en charge un nombre illimité d'arguments de position et de mots-clés. Vous pouvez y parvenir en concevant la fonction wrapper imbriquée pour accepter `*args` et `**kwargs` et les transmettre à la fonction cible. De plus, vous devez utiliser « functools.wraps » sur la fonction wrapper pour conserver les métadonnées de docstring et de nom de la fonction d'origine.
Sortie de code et d'exécution
Ce script montre l'écriture d'un décorateur de journalisation et l'encapsulation d'une fonction pour inspecter les entrées, les sorties et les métadonnées.
from functools import wraps
# 1. Defining a decorator
def log_execution(func):
@wraps(func) # Preserves original function metadata
def wrapper(*args, **kwargs):
print(f"[Log] Calling function: {func.__name__} with args: {args}")
result = func(*args, **kwargs)
print(f"[Log] Finished {func.__name__}. Result: {result}")
return result
return wrapper
# 2. Applying the decorator using @ syntax
@log_execution
def add_numbers(a, b):
"""Adds two numbers and returns the sum."""
return a + b
# 3. Invoking the decorated function
sum_result = add_numbers(15, 25)
print("Sum Result:", sum_result)
# Verifying metadata preservation
print("Docstring preserved:", add_numbers.__doc__)[Log] Calling function: add_numbers with args: (15, 25)
[Log] Finished add_numbers. Result: 40
Sum Result: 40
Docstring preserved: Adds two numbers and returns the sum.Mise en œuvre étape par étape
- Définissez une fonction de décorateur externe qui prend la fonction cible comme argument.
- Importez et appliquez @functools.wraps(func) sur votre fonction wrapper imbriquée pour protéger les métadonnées d'origine.
- Implémentez wrapper(*args, **kwargs) pour capturer les variables d'entrée, injecter de la logique et appeler la fonction cible.
- Renvoie l’objet fonction wrapper du bloc d’en-tête du décorateur.
- Appliquez le décorateur en utilisant @decorator_name directement au-dessus de la signature de la fonction cible.
Foire aux questions
Pourquoi @functools.wraps est-il nécessaire chez les décorateurs ?
Sans wraps, la fonction décorée perd son identité d'origine (ses attributs __name__ et __doc__ sont remplacés par ceux de la fonction wrapper imbriquée), ce qui rend le débogage et l'introspection du code difficiles.
Puis-je appliquer plusieurs décorateurs à une seule fonction ?
Oui ! Vous pouvez enchaîner les décorateurs en empilant plusieurs lignes @. Python les applique de bas en haut (le plus proche de la définition de fonction s'exécute en premier).
Sujets connexes
Maîtrisez *args et **kwargs en Python. Apprenez à écrire des fonctions flexibles avec des arguments de position et de mot-clé dynamiques, à décompresser des collections et à créer des fonctions wrapper.
Comment utiliser les fonctions Lambda en PythonApprenez à utiliser les fonctions lambda en Python. Maîtrisez les fonctions anonymes, les rappels en ligne et le tri des données de liste avec des clés lambda.
Ressources Python recommandées
Développez vos connaissances avec des didacticiels interactifs, des aide-mémoire et des comparaisons de codes associés.
Variables et types de données Python expliqués
Comprendre les variables Python et les types de données de base (chaînes, entiers, flottants, booléens). Un guide complet pour débutants sur l'affectation de mémoire en Python.
Aide-mémoire sur les méthodes du dictionnaire Python
Apprenez les méthodes du dictionnaire Python. Guide de référence complet pour les insertions, les récupérations, les mises à jour et les vérifications de paires clé-valeur.
Python vs JavaScript : quel langage de programmation est le meilleur ?
Une comparaison complète entre Python et JavaScript. Explorez les différences de syntaxe, les performances, les cas d'utilisation (backend et frontend) et des exemples de codage.