Декоратор с аргументами (декоратор фабрики)

Декоратор принимает только один аргумент: функцию, которую нужно декорировать. Нет возможности передать другие аргументы.

Но дополнительные аргументы часто желательны. Хитрость заключается в том, чтобы создать функцию, которая принимает произвольные аргументы и возвращает декоратор.

Функции декоратора

 def decoratorfactory(message):
    def decorator(func):
        def wrapped_func(*args, **kwargs):
            print('The decorator wants to tell you: {}'.format(message))
            return func(*args, **kwargs)
        return wrapped_func
    return decorator

@decoratorfactory('Hello World')
def test():
    pass

test()

 

Декоратор хочет сказать вам: Hello World

Важная заметка:

С такой декоратор фабрикой вы должны вызвать декоратор с парой скобок:

 @decoratorfactory # Without parentheses
def test():
    pass

test()
 

TypeError: decorator () отсутствует 1 обязательный позиционный аргумент: 'func'

Классы декораторов

 def decoratorfactory(*decorator_args, **decorator_kwargs):

    class Decorator(object):
        def __init__(self, func):
            self.func = func

        def __call__(self, *args, **kwargs):
            print('Inside the decorator with arguments {}'.format(decorator_args))
            return self.func(*args, **kwargs)

    return Decorator

@decoratorfactory(10)
def test():
    pass

test()

 

Внутри декоратор с аргументами (10,)