CodeGym /Cours /Python SELF FR /La puissance des décorateurs

La puissance des décorateurs

Python SELF FR
Niveau 14 , Leçon 2
Disponible

6.1 Décorateurs pour les méthodes de classe

Les décorateurs peuvent également être utilisés pour les méthodes de classe. Il est important de se rappeler que pour les méthodes de classe, il est nécessaire de passer correctement les arguments self ou cls.

On n'a pas encore abordé les subtilités du travail avec les classes, mais je voudrais que vous sachiez que cette fonctionnalité des décorateurs existe.


def log_method_call(func):
    def wrapper(self, *args, **kwargs):
        print(f"Appel de la méthode {func.__name__}")
        return func(self, *args, **kwargs)

    return wrapper
        
class MyClass:
    @log_method_call
    def say_hello(self):
        print("Hello from MyClass!")
        
obj = MyClass()
obj.say_hello()

Explication

Décorateur (log_method_call): Ce décorateur prend une méthode func et renvoie une nouvelle fonction wrapper qui affiche un message avant l'appel de la méthode.

Méthode de classe avec décorateur (say_hello): La méthode say_hello est enveloppée par le décorateur log_method_call, ce qui ajoute un comportement supplémentaire lors de son appel.

Sortie :


Appel de la méthode say_hello
Hello from MyClass!

6.2 Plusieurs décorateurs

Vous pouvez utiliser plusieurs décorateurs pour une fonction, en les superposant les uns aux autres. Les décorateurs sont appliqués dans l'ordre inverse de leur déclaration.


def decorator1(func):
    def wrapper():
        print("Décorateur 1")
        func()

    return wrapper
        
def decorator2(func):
    def wrapper():
        print("Décorateur 2")
        func()

    return wrapper
        
@decorator1
@decorator2
def say_hello():
    print("Hello!")
        
say_hello()

Explication

Décorateurs (decorator1 et decorator2): Ces décorateurs ajoutent leurs messages avant l'appel de la fonction func.

Fonction avec décorateurs (say_hello): La fonction say_hello est enveloppée par les deux décorateurs. Le decorator2 est appliqué en premier, puis le decorator1.

Sortie :


# Décorateur 1
# Décorateur 2
Hello!

6.3 Décorateurs intégrés

Python fournit plusieurs décorateurs intégrés pour des tâches standard, telles que les méthodes statiques, les méthodes de classe et les propriétés.

@staticmethod

Le décorateur @staticmethod est utilisé pour créer une méthode statique qui ne nécessite pas d'instance de classe pour être appelée.


class MyClass:
    @staticmethod
    def static_method():
        print("Ceci est une méthode statique.")
        
MyClass.static_method()

@classmethod

Le décorateur @classmethod est utilisé pour créer une méthode de classe qui accepte la classe (et non une instance) en tant que premier argument.


class MyClass:
    @classmethod
    def class_method(cls):
        print(f"Ceci est une méthode de classe {cls.__name__}.")
        
MyClass.class_method()

@property

Le décorateur @property est utilisé pour créer des getters, setters et deleters pour les attributs.


class MyClass:
    def __init__(self, value):
        self.hidden_value = value
        
    @property
    def value(self):
        return self.hidden_value
        
    @value.setter
    def value(self, new_value):
        self.hidden_value = new_value
        
obj = MyClass(10)
print(obj.value)  # Sortie : 10
obj.value = 20
print(obj.value)  # Sortie : 20

Ce sont des décorateurs intégrés, leur bon fonctionnement est assuré par l'interpréteur Python lui-même.

6.4 Exemples d'utilisation des décorateurs

Journalisation

Les décorateurs peuvent être utilisés pour journaliser les appels de fonctions et de méthodes.


def log_call(func):
    def wrapper(*args, **kwargs):
        print(f"Appel de la fonction {func.__name__} avec les arguments {args} et {kwargs}")
        return func(*args, **kwargs)

    return wrapper
        
@log_call
def add(x, y):
    return x + y
        
print(add(2, 3))

Contrôle d'accès

Les décorateurs peuvent être utilisés pour contrôler l'accès aux fonctions et méthodes.


def require_authentication(func):
    def wrapper(*args, **kwargs):
        if not args[0].is_authenticated:
            raise PermissionError("Utilisateur non authentifié.")
        return func(*args, **kwargs)
        
    return wrapper
        
class User:
    def __init__(self, is_authenticated):
        self.is_authenticated = is_authenticated
        
    @require_authentication
    def view_profile(self):
        print("Profil utilisateur")
        
user = User(is_authenticated=True)
user.view_profile()  # Appel réussi
        
user2 = User(is_authenticated=False)
user2.view_profile()  # PermissionError: Utilisateur non authentifié.

Mise en cache

Les décorateurs peuvent être utilisés pour mettre en cache les résultats d'une fonction.


def cache(func):
    cached_results = {}

    def wrapper(*args):
        if args in cached_results:
            return cached_results[args]
        result = func(*args)
        cached_results[args] = result
        return result

    return wrapper

@cache
def fib(n):
    if n < 2:
        return n
    return fib(n - 1) + fib(n - 2)

print(fib(35))
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION