{}const=>[]async()letfn</>var
DéveloppementPython

Décorateurs en Python : étendre les fonctionnalités sans modifier le code

Apprenez à utiliser les décorateurs Python pour une extension élégante des fonctionnalités. Analysons des exemples pratiques : journalisation, mise en cache, mesure du temps d'exécution et vérification des droits d'accès. Des explications claires avec des exemples de code pour les développeurs débutants et expérimentés.

К

Kodik

Auteur

5 min de lecture

Imaginez que vous développez une application Web et que vous devez enregistrer chaque appel d'API, vérifier les droits d'accès des utilisateurs et mesurer le temps d'exécution des fonctions. Vous pouvez, bien sûr, copier le même code dans chaque fonction, mais il existe un moyen plus élégant : les décorateurs. C'est l'un des outils Python les plus puissants qui vous permet de modifier le comportement des fonctions sans modifier leur code source.

Que sont les décorateurs

Un décorateur est une fonction qui prend une autre fonction comme argument et renvoie une nouvelle fonction avec des fonctionnalités étendues. Cela semble compliqué ? En fait, tout est plus simple qu'il n'y paraît.

def my_decorator(func):
    def wrapper():
        print("Something happens before the function is called")
        func()
        print("Something happens after calling the function")
    return wrapper

@my_decorator
def say_hello():
    print("Hi!")

say_hello()

Résultat de l'exécution :

Что-то происходит до вызова функции
Привет!
Что-то происходит после вызова функции

Le symbole @ est un sucre syntaxique Python. L'entrée @my_decorator avant la fonction est équivalente à say_hello = my_decorator(say_hello).

🔥 100 000+ étudiants déjà avec nous

Marre de lire la théorie ?
Il est temps de coder !

Kodik — une appli où tu apprends à coder par la pratique. Mentor IA, leçons interactives, projets réels.

🤖 IA 24/7
🎓 Certificats
💰 Gratuit
🚀 Commencer
Ont rejoint aujourd'hui

Décorateurs avec arguments

Mais que faire si notre fonction accepte des paramètres ? Pour cela, nous utilisons *args et **kwargs :

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f"Hi, {name}!")

greet("Alexey")

Conclusion :

Привет, Алексей!
Привет, Алексей!
Привет, Алексей!

Ici, nous avons créé un décorateur avec un paramètre qui répète l'appel de la fonction un nombre de fois spécifié.

Exemples pratiques de décorateurs

Mesure du temps d'exécution

import time
from functools import wraps

def timer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"The {func.__name__} function was executed in {end - start:.4f} seconds")
        return result
    return wrapper

@timer
def heavy_computation():
    time.sleep(2)
    return "Done"

heavy_computation()

Faites attention à @wraps(func) — c'est un décorateur intégré du module functools, qui enregistre les métadonnées de la fonction d'origine (nom, documentation, etc.).

Mise en cache des résultats

def memoize(func):
    cache = {}
    @wraps(func)
    def wrapper(*args):
        if args not in cache:
            cache[args] = func(*args)
        return cache[args]
    return wrapper

@memoize
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(100))  # S'exécute instantanément grâce à la mise en cache

Vérification des droits d'accès

def require_auth(func):
    @wraps(func)
    def wrapper(user, *args, **kwargs):
        if not user.get('is_authenticated'):
            raise PermissionError("Authorization required")
        return func(user, *args, **kwargs)
    return wrapper

@require_auth
def delete_account(user, account_id):
    print(f"Account {account_id} has been deleted")

user = {'is_authenticated': True, 'username': 'admin'}
delete_account(user, 123)

Chaînes de décorateurs

Les décorateurs peuvent être combinés en appliquant plusieurs fonctions à une seule :

@timer
@memoize
def complex_calculation(x, y):
    time.sleep(1)
    return x ** y

# Le premier appel prendra ~ 1 seconde
complex_calculation(2, 10)

# Le deuxième appel sera instantané (le résultat est mis en cache)
complex_calculation(2, 10)

Les décorateurs sont appliqués de bas en haut, c'est-à-dire d'abord memoize, puis timer.

Les classes en tant que décorateurs

Les décorateurs ne doivent pas nécessairement être des fonctions. Vous pouvez utiliser les classes suivantes :

class CountCalls:
    def __init__(self, func):
        self.func = func
        self.count = 0
    
    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"Call #{self.count} of the {self.func.__name__} function"_} ")
        return self.func(*args, **kwargs)

@CountCalls
def process_data():
    print("Processing data...")

process_data()
process_data()
process_data()

Décorateurs Python intégrés

Python fournit plusieurs décorateurs intégrés utiles :

  • @property — transforme la méthode en attribut de classe

  • @staticmethod — crée une méthode statique

  • @classmethod — crée une méthode de classe

  • @functools.lru_cache — mise en cache avec limitation de taille

  • @dataclass — création automatique de méthodes de classe

from functools import lru_cache

@lru_cache(maxsize=128)
def expensive_function(param):
    # Calculs complexes
    return param * 2

Quand utiliser les décorateurs

Les décorateurs sont idéaux pour les tâches qui doivent être appliquées à de nombreuses fonctions : journalisation, validation des données d'entrée, gestion des exceptions, contrôle d'accès, mise en cache, mesure des performances, logique de nouvelle tentative en cas d'erreurs réseau. Ils aident à respecter le principe DRY (Don't Repeat Yourself) et rendent le code plus propre et plus clair.

Problèmes potentiels

Malgré toute la puissance des décorateurs, il faut se souvenir de quelques points. L'utilisation excessive de décorateurs peut rendre le débogage du code plus difficile. Les décorateurs ajoutent de petits frais généraux aux performances. Il est important de toujours utiliser @wraps pour enregistrer les métadonnées de la fonction. Les chaînes de plusieurs décorateurs peuvent réduire la lisibilité du code.

Résumé

Les décorateurs sont un moyen élégant de modifier et d'étendre les fonctionnalités du code sans le modifier. Ils sont largement utilisés dans des frameworks populaires tels que Flask et Django, et comprendre leur fonctionnement vous simplifiera considérablement la vie en tant que développeur. Commencez par des décorateurs simples pour la journalisation ou la mesure du temps, et vous découvrirez progressivement de plus en plus de situations où ils seront utiles.

Vous souhaitez maîtriser les décorateurs et autres fonctionnalités avancées de Python en pratique ?

Annexe Code a été créé spécialement pour que vous puissiez apprendre la programmation à un rythme confortable, avec des explications claires en russe et des exemples pratiques réels. Nous analysons des sujets complexes dans un langage simple, des bases aux techniques professionnelles. Chaque leçon est conçue pour que vous ne vous contentiez pas de mémoriser la syntaxe, mais que vous compreniez comment appliquer vos connaissances à des projets réels.

Et si vous avez des questions pendant la formation, bienvenue dans notre Chaîne Telegram! C'est une communauté vivante de développeurs où vous pouvez poser n'importe quelle question et obtenir une réponse détaillée. Notre atmosphère est amicale et instructive : chaque jour, nous analysons les meilleurs sujets en développement, partageons nos expériences et nous aidons mutuellement à grandir. Rejoignez Kodik : commencez votre parcours de programmation avec ceux qui savent vraiment comment rendre l'apprentissage efficace et intéressant !

🎯Arrête de reporter

Tu as aimé l'article ?
Place à la pratique !

Avec Kodik, tu ne lis pas seulement — tu codes immédiatement. Théorie + pratique = vraies compétences.

Pratique instantanée
🧠L'IA explique le code
🏆Certificat

Sans inscription • Sans carte