ProgrammationDéveloppeur Backend

Qu'est-ce que les décorateurs pour les méthodes d'instance en Python, pourquoi sont-ils utilisés et comment les appliquer correctement ? Expliquez le fonctionnement des décorateurs classiques à l'aide d'exemples de fonctions et de méthodes.

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Les décorateurs en Python sont historiquement apparus comme un moyen de rendre le code plus compact et lisible, en encapsulant des comportements répétitifs autour des fonctions et des méthodes. Avant l'apparition de la syntaxe @decorateur, ils étaient appliqués de manière explicite, ce qui compliquait la compréhension du code. Aujourd'hui, les décorateurs jouent un rôle clé dans l'organisation de la logique, les vérifications répétées, le logging, la mise en cache, etc.

Le problème lors de l'utilisation des décorateurs est de bien gérer les différences entre les fonctions, les méthodes d'instance et les méthodes statiques/de classe. Des erreurs se produisent souvent en raison de la perte d'informations sur la méthode, de lier tardivement ou prématurément self, ainsi que de la signature de la fonction.

La solution consiste, lors de l'écriture de décorateurs universels, à utiliser le module functools.wraps pour préserver les métadonnées, et à prêter une attention particulière au type de l'objet décoré (par exemple, prendre en compte correctement que les méthodes d'instance reçoivent self comme premier argument).

Exemple de code :

import functools def my_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): print(f"Avant la fonction : {func.__name__}") result = func(*args, **kwargs) print(f"Après la fonction : {func.__name__}") return result return wrapper class Example: @my_decorator def method(self, x): print(f"Méthode appelée avec {x}") ex = Example() ex.method(5)

Caractéristiques clés :

  • Le décorateur au niveau de la méthode reçoit une fonction qui attend self comme premier argument.
  • Il est recommandé d'utiliser functools.wraps pour préserver les métadonnées originales.
  • Les décorateurs peuvent être paramétrés pour plus de flexibilité.

Questions pièges.

Si l'on utilise un décorateur écrit pour une fonction sur une méthode de classe, est-il obligatoire d'utiliser functools.wraps, et que se passe-t-il avec self ?

Non, le décorateur fonctionne, mais sans wraps, le nom de la fonction, l'aide IDE et la documentation sont perdus. Self sera toujours le premier paramètre, mais la perte des métadonnées compliquera le débogage et la réflexion.

def bad_decorator(f): def wrapper(*args, **kwargs): print("décoré") return f(*args, **kwargs) return wrapper class Test: @bad_decorator def foo(self): pass print(Test().foo.__name__) # wrapper

Peut-on appliquer le même décorateur à la fois à une méthode d'instance et à une méthode statique ?

Oui, mais il faut se rappeler que les méthodes statiques ne reçoivent pas self comme premier argument. Si le décorateur est censé fonctionner avec self, il y aura des erreurs avec @staticmethod/ @classmethod.

Comment le décorateur influence-t-il la signature de la méthode et l'auto-complétion ?

Plus simplement : sans functools.wraps, la signature et la docstring sont perdues, IDE et de nombreux outils de suggestion cessent de fonctionner correctement.

Erreurs courantes et anti-patterns

  • Non-utilisation de functools.wraps — perte du nom de la fonction, de la docstring, rendant le débogage plus difficile.
  • Le décorateur est écrit pour une fonction, sans tenir compte de la présence de self — ne fonctionne pas correctement sur les méthodes.
  • Réutilisation du même décorateur sans tenir compte du contexte (méthode statique/méthode de classe/méthode ordinaire).

Exemple de la vie

Cas négatif : Décorateurs sans functools.wraps dans toutes les méthodes de la classe.
Avantages : prototype rapide, ça fonctionne.
Inconvénients : impossible de rechercher des erreurs dans la pile, l'IDE ne suggère pas la signature.

Cas positif : Les décorateurs utilisent functools.wraps, le code est documenté.
Avantages : lisibilité, maintenance, confort IDE.
Inconvénients : ajout minimal à la syntaxe et attention.