Декораторы классов Python — как работают и примеры

В этом руководстве вы узнаете, как работают декораторы классов Python. После урока вы научитесь определять классы в качестве декораторов.

Введение в декораторы классов Python

Вы узнаете, как использовать функции для определения декораторов. Например, следующая функция звездочки выводит несколько символов * до и после вызова декорированной функции:

def star(n):
    def decorate(fn):
        def wrapper(*args, **kwargs):
            print(n*'*')
            result = fn(*args, **kwargs)
            print(result)
            print(n*'*')
            return result
        return wrapper
    return decorate

Звездочка — фабрика декораторов, которая возвращает декоратор. Он принимает аргумент, указывающий количество отображаемых символов *.

Ниже показано, как использовать фабрику декоратора *:

@star(5)
def add(a, b):
    return a + b


add(10, 20)

Выход:

*****
30
*****

Фабрика декораторов star() принимает аргумент и возвращает вызываемый объект. Вызываемый объект принимает аргумент(fn), который представляет собой функцию, которая будет декорирована. Кроме того, вызываемый объект может получить доступ к аргументу(n), переданному фабрике декораторов.

Экземпляр класса может быть вызываемым, если он реализует метод __call__. Поэтому вы можете сделать метод __call__ декоратором.

В следующем примере фабрика декораторов перезаписывается с использованием вместо этого класса:

class Star:
    def __init__(self, n):
        self.n = n

    def __call__(self, fn):
        def wrapper(*args, **kwargs):
            print(self.n*'*')
            result = fn(*args, **kwargs)
            print(result)
            print(self.n*'*')
            return result
        return wrapper

И вы можете использовать класс Star в качестве декоратора следующим образом:

@Star(5)
def add(a, b):
    return a + b

@Star(5) возвращает экземпляр класса Star. Этот экземпляр является вызываемым, поэтому вы можете сделать что-то вроде:

add = Star(5)(add)

Таким образом, вы можете использовать вызываемые классы для декорирования функций.

Положим все это вместе:

from functools import wraps


class Star:
    def __init__(self, n):
        self.n = n

    def __call__(self, fn):
        @wraps(fn)
        def wrapper(*args, **kwargs):
            print(self.n*'*')
            result = fn(*args, **kwargs)
            print(result)
            print(self.n*'*')
            return result
        return wrapper


@Star(5)
def add(a, b):
    return a + b


add(10, 20)
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *