Les décorateurs en Python permettent de modifier ou d’améliorer des fonctions ou des classes sans modifier directement leur code source.
Ils utilisent le concept des fermetures (closure
en anglais) et des fonctions d’ordre supérieur pour envelopper la fonction ou la classe d’origine, en ajoutant des fonctionnalités avant ou après l’exécution du code enveloppé.
Cela ressemble aux intercepteurs de navigation de Vue Router ou aux attributs personnalisés ou middlewares en C#.
Voyons étape par étape comment les coder et les utiliser.
Exemple de base
Commençons par les bases. Vous définissez un décorateur Python comme suit :
|
|
Examinons maintenant des cas d’utilisation spécifiques.
Décorateur sans contribution de l’appelant
C’est la forme la plus simple d’un décorateur. Il n’a pas d’autres arguments que la fonction qu’il décore. Entre les deux, il affiche Dans le décorateur avant d'appeler {nom de la fonction}
et Fonction {nom de la fonction} appelée. Compléter la logique du décorateur...
.
|
|
Dans cet exemple, le décorateur log_function_call
ajoute la journalisation avant et après l’appel de la fonction sans avoir besoin de l’intervention de l’appelant.
Décorateur avec entrée de l’appelant
Lorsque vous avez besoin de passer des arguments au décorateur lui-même, vous devez ajouter une autre couche de fonctions :
|
|
Dans ce cas, le décorateur repeat
accepte un argument times
qui détermine combien de fois la fonction décorée greet
doit être appelée.
Voici comment cela fonctionne :
repeat(times)
est appelé avec l’argument, retournant la fonctiondecorator
.- La fonction
décorateur
enveloppe alors la fonction originale (greet
dans ce cas). - Lorsque
greet
est appelée, elle appelle en fait la fonctionwrapper
, qui exécute la fonctiongreet
originalefois
un certain nombre de fois.
L’ordre est important
Vous pouvez aussi combiner plusieurs décorateurs :
|
|
Cela équivaut à :
|
|
L’ordre des décorateurs est crucial et dépend de votre logique métier.
Exemple pratique
Supposons que nous ayons ce point de terminaison qui intercepte un appel entrant (webhook) :
|
|
Les décorateurs que nous voulons examiner sont log_headers
et validate_twilio_request
.
Ils ressemblent à ceci :
|
|
Maintenant, un problème peut survenir avec le décorateur log_headers
qui n’exécute pas et ne trace pas les en-têtes. Pourquoi ?
En Python, les décorateurs sont appliqués de bas en haut. Dans notre cas d’utilisation, nous aurions l’équivalent de ceci :
|
|
Le décorateur validate_twilio_request
échoue si la signature dans l’en-tête X-Twilio-Signature
est incorrecte et donc le décorateur log_headers
ne s’exécutera pas du tout à cause de l’erreur soulevée :
|
|
Pour déboguer l’échec du décorateur validate_twilio_request
, c’est dommage de ne pas tracer les en-têtes.
La solution est simple : placez log_headers
en premier et le fichier de traces contiendra tous les en-têtes reçus lors de la requête.
Suivez-moi !
Merci d’avoir lu cet article. Assurez-vous de me suivre sur X, de vous abonner à ma publication Substack et d’ajouter mon blog à vos favoris pour ne pas manquer les prochains articles.
Crédit: Photo de Nataliya Vaitkevich.