les décorateurs en python
Les décorateurs sont des outils très puissants et utiles en Python, car ils permettent aux programmeurs de modifier le comportement d'une fonction ou d'une classe. Les décorateurs nous permettent d’envelopper(wrapper) une autre fonction afin d’étendre le comportement de la fonction enveloppée, sans la modifier de façon permanente.
Dans Decorators, les fonctions sont prises comme argument dans une autre fonction, puis appelées à l'intérieur de la fonction wrapper.
Nous utilisons @func_name pour spécifier un décorateur à appliquer à une autre fonction.
def decorateur(fun): # fonction interne qui affiche bonjour avant l'appel de la fonction def hello(para): return "Bonjour "+fun(para) return hello @decorateur def Test(nom): return nom print(Test("Mostafa")) # -> Bonjour Mostafa
Attacher des données
Les décorateurs peuvent également être utiles pour attacher des données (ou ajouter un attribut) à des fonctions.
def add_data(func): func.donnee=5 return func @add_data def somme(x,y): return x+y print(somme(3,4)) print(somme.donnee)
'somme()' retourne la somme de x et y passée en arguments mais il est encapsulé par une fonction décoratrice
- appeler somme(3, 4) donnerait simplement la somme de deux nombres
- mais lorsque nous appelons 'somme.donnee', alors la fonction 'somme()' est passé dans la fonction décoratrice 'add_data' en argument et cette fonction retourne la fonction 'somme' avec un attribut 'donnee' avec une valeur de 5.
Temps d'exécution d'une fonction
import time # decorateur pour calculer le temps d'exécution d'une fonction def Temps_execution(func): # *args récupérer la liste des arguments # **kwargs récupérer les arguments (clé : valeur) def calculer(*args, **kwargs): # début d'execution begin = time.time() func(*args, **kwargs) # fin d'execution end = time.time() print("le temps d'execution de la fonction {} est {}: ".format(func.__name__, end - begin)) return calculer @Temps_execution def factorial(num): f=1 for i in range(2,num+1): f*=i print(f) factorial(70)
Décorateurs avec paramètres
@nom_decorateur(params) def nom_fonction(): ''' Function implementation'''
# Decorateur avec parametres def decorateur(*args, **kwargs): def hello(func): print("annee : ",args[0]) print("Site : ", kwargs['site']) print("ville : ", kwargs['ville']) return func return hello @decorateur(2019, site = "Developpement-informatique.com", ville="Meknès") def TEST(): print("fonction test") TEST()
Mémorisation à l'aide de décorateurs
La récursivité est une technique de programmation dans laquelle une fonction s’appelle de manière répétée jusqu’à ce qu’une condition de terminaison soit remplie.
Parmi les exemples où la récursivité est utilisée, citons: calcul de séries de fibonacci, factorielles, etc.
Mais le problème avec ces dernières est que dans l’arbre de récursivité, il est possible que le sous-problème déjà résolu soit à nouveau résolu, ce qui ajoute à une surcharge
La mémorisation est une technique d’enregistrement des résultats intermédiaires afin d’éviter des calculs répétés et d’accélérer les programmes.
Il peut être utilisé pour optimiser les programmes utilisant la récursivité.
En Python, la mémorisation peut être réalisée à l'aide des fonctions décoratrices.
# décorateur de mémorisation def memo_fib(func): memoire = {} # Récupérer l'élément si il est déjà enregistré # calculer sinon def calculer(num): if num not in memoire: memoire[num] = func(num) return memoire[num] return calculer @memo_fib def fib(num): if num <2 : return 1 else: return fib(num-1)+fib(num-2) print(fib(5))
- memo_fib : L’objectif principal est de stocker les résultats intermédiaires dans la variable appelée mémoire.
- La deuxième fonction appelée fib est la fonction permettant de calculer la suite de fibonacci. Il a été annoté par un décorateur (la fonction memo_fib). la fonction fib a accès à la variable de memoire grâce au concept de fermeture.
- Lorsque fib(5) est appelé, les opérations récursives ont lieu en plus du stockage des résultats intermédiaires. Chaque fois qu'un calcul doit être effectué, il est vérifié si le résultat est disponible en mémoire. Si oui, alors il est utilisé, sinon, la valeur est calculée et stockée en mémoire.