Python – Améliorez votre code avec les décorateurs

-

Dans cet article, nous allons voir à quel point les décorateurs sont puissants. Si vous êtes nouveau à Python (et peut-être même si vous ne l’êtes pas), vous n’avez probablement jamais entendu parler de cette construction. C’est quelque chose de spécifique à Python, qui permet de définir un comportement général commun à de nombreuses méthodes dans une fonction séparée. Moi-même, j’ai découvert cela que tout récemment !

Par exemple, supposons que nous ayons les méthodes suivantes :

def sum(a, b):
  return a+b
def subtract(a, b):
  return a-b

Nous voulons maintenant imprimer le résultat dans la console, avant de le renvoyer. Que devons-nous faire ? La première idée est d’ajouter une instruction print dans toutes les fonctions. Mais que se passe-t-il si nous décidons de sauvegarder le résultat dans un fichier ? Nous devrions à nouveau modifier toutes les fonctions.

Au lieu de cela, nous pouvons créer un décorateur log_result et l’ajouter aux méthodes :

@log_result
def sum(a, b):
  return a+b
@log_result
def subtract(a, b):
  return a-b

Et maintenant, si nous voulons changer l’endroit où nous écrivons la sortie, nous devons juste changer le code dans log_result .

Qu’est-ce qu’un décorateur (decorator) ?

Nous avons vu comment les décorateurs peuvent être utilisés, mais qu’est-ce qu’un décorateur exactement ?
Pour vous donner une définition formelle,

A decorator is a function that takes another function and extends the behavior of the latter function without explicitly modifying it.

En traduction libre :

Un décorateur est une fonction qui prend une autre fonction et étend le comportement de cette dernière sans la modifier explicitement.
Décortiquons cela morceau par morceau.

Tout d’abord, un décorateur est une fonction qui prend une autre fonction comme paramètre : cela signifie que nous définirons le décorateur log_result comme :

def log_result(func):

Ensuite, nous devons modifier cette fonction et retourner la version modifiée.
Nous pouvons donc créer une fonction interne (que j’ai appelée inner pour simplifier) qui exécute func , imprime le résultat et renvoie enfin cette valeur :

def log_result(func):
  def inner():
    res = func()
    print(res)
    return res

Enfin, le décorateur doit retourner la fonction modifiée :

def log_result(func):
  def inner():
    res = func()
    print("The result is ", res)
    return res
  
  return inner

Nous avons créé notre premier décorateur ! Enfin, pas vraiment. Il ne fonctionne que si la fonction à laquelle nous l’ajoutons n’a pas de paramètres. Par exemple :

@log_result
def get_even_digits():
  return [0, 2, 4, 6, 8]

Lorsque nous appelons cette fonction, le journal s’imprime à l’écran :

>>> l = get_even_digits()
The result is [0, 2, 4, 6, 8]

Cependant, si nous essayons de l’utiliser avec les méthodes sum et subtract de la version précédente, le code ne s’exécutera pas correctement.

Le problème est que nous n’avons pas donné à la fonction modifiée la possibilité de recevoir les paramètres qui devraient être passés à func . Heureusement, ce problème peut être résolu facilement. Nous allons redéfinir inner comme suit :

def log_result(func):
  def inner(**kwargs):
    res = func(kwargs)
    print("The result is ", res)
    return res
  
  return inner

Maintenant, inner peut obtenir n’importe quel nombre de paramètres, et les passer directement à la fonction. Nous l’avons fait !

>>>s = sum(3, 5)
The result is 8
>>>d = subtract(8,5)
The result is 3

Décorateurs avec paramètres

Enfin, nous pouvons vouloir passer des paramètres supplémentaires au décorateur. Par exemple, nous pouvons vouloir imprimer également un nom avec le résultat, afin de savoir de quelle opération provient ce journal.

Pour ce faire, nous devons modifier légèrement la fonction :

def log_with_name(name):
  def log_result(f):
    def inner(x):
      res = f(x)
      print(name + ": " + str(res))
      return inner
  return log_result

Voyons ce qui se passe. La fonction log_with_name prend la chaîne du nom et renvoie le décorateur qui sera ensuite appliqué à une fonction.
Il peut être utilisé exactement comme avant :

@log_with_name("Sum")
def sum(a, b):
  return a+b
@log_with_name("Difference")
def subtract(a, b):
  return a-b

Et le résultat sera :

>>> s = sum(3, 5)
Sum: 8
>>> d = subtract(8, 3)
Difference: 5

Conclusion

Merci d’avoir lu jusqu’au bout ! Voici d’autres ressources sur les décorateurs :

Alfred
Alfredhttps://www.alfreddagenais.com
Salut ! Moi, c'est Alfred, développeur dans l’âme et explorateur de l'infini Web. Je suis constamment à la recherche de nouvelles idées et je pense que le développement web et l'informatique ont le pouvoir de transformer le monde. Je suis un grand admirateur de l'expérimentation, parce que c'est souvent de là que naissent les idées les plus créatives. Je suis convaincu que l'humour est un ingrédient clé de la vie, alors j'essaie toujours de glisser une blague ou deux dans mon code (pas toujours facile à comprendre, mais c'est le risque à prendre). En dehors de la programmation, j'aime passer du temps avec ma famille et mes amis, découvrir de nouveaux endroits et cuisiner des plats délicieux (du moins, j'essaie). Si vous voulez discuter de développement web, d'innovation, ou tout simplement échanger des blagues, n'hésitez pas à me contacter. Je suis toujours partant pour une bonne conversation !

Share this article

Recent posts

Popular categories

LAISSER UN COMMENTAIRE

S'il vous plaît entrez votre commentaire!
S'il vous plaît entrez votre nom ici

Recent comments