Exercice 45 / 100

Décorateurs

Cree un decorateur @timer qui mesure le temps d'execution d'une fonction (sans l'afficher). Teste avec une fonction qui calcule sum(range(1000000)) et affiche le resultat.

Un décorateur est une fonction qui prend une autre fonction en argument, lui ajoute un comportement, et la renvoie. Très utilisé pour logger, mesurer le temps, vérifier des permissions, etc. — sans modifier le code de la fonction décorée.

Syntaxe @

@mon_decorateur def ma_fonction(): ...

C'est strictement équivalent à :

def ma_fonction(): ... ma_fonction = mon_decorateur(ma_fonction)

Forme d'un décorateur

def decorateur(func): def wrapper(*args, **kwargs): # avant l'appel result = func(*args, **kwargs) # après l'appel return result return wrapper

Les points clés

- le décorateur prend une fonction en entrée et renvoie une nouvelle - le wrapper accepte *args, **kwargs (= n'importe quels arguments) - il appelle la fonction d'origine au milieu
Un décorateur enveloppe la fonction dans un wrapper qui s'exécute avant et après elle, sans que le code de la fonction d'origine soit modifié

Exemple : @timer

import time
def timer(func): def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) elapsed = time.time() - start # On pourrait print elapsed ici, mais on choisit de le garder silencieux return result return wrapper
@timer def calcul_long(): total = sum(range(1000000)) return total
resultat = calcul_long() print(f'Résultat: {resultat}')

Décorateurs utiles de la stdlib

@functools.lru_cache mémoïse les résultats (cache automatique) @functools.wraps préserve le nom et la docstring (à utiliser dans tes décorateurs) @property transforme une méthode en attribut @staticmethod méthode sans self @classmethod méthode avec cls

Frameworks célèbres qui utilisent massivement les décorateurs : Flask (@app.route), FastAPI (@router.get), pytest (@pytest.fixture).

exercise.py

Envie d'aller plus loin ? Découvrez nos formations certifiées Bac+2 à Bac+5 →