Декораторы с параметрами

категория: Python 3

Привет! Сегодня поговорим о декораторах с параметрами. О самих декораторах упоминать, думаю, особо не стоит - так как там все просто: функция которая внутри себя вызывает функцию и делает что-то до ее вызова или после. Паттерн "Декоратор" - это  структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту.

Декоратор с параметрами - это по сути тоже самое, что и простой декоратор, только нужно обернуть еще в одну функцию которая закинет параметры в область видимости. Покажу три разных вида: обычный, с использванием functools.wraps и модуля wrapt.

def args_decorator(arg1, arg2):
    def _outer_wrapper(wrapped_function):
        def _wrapper(*args, **kwargs):
            # делаем что-то до вызова функции
            result = wrapped_function(*args, **kwargs)
            # делаем что-то после вызова функции
            result = result * arg1 * arg2
            return result
        return _wrapper
    return _outer_wrapper

def args_decorator_with_wraps(arg1, arg2):
    def _outer_wrapper(wrapped_function):
        @functools.wraps(wrapped_function)
        def _wrapper(*args, **kwargs):
            # делаем что-то до вызова функции 
            result = wrapped_function(*args, **kwargs) 
            # делаем что-то после вызова функции 
            result = result * arg1 * arg2
            return result
        return _wrapper
    return _outer_wrapper

def args_decorator_with_wrapt(arg1, arg2):
    @wrapt.decorator
    def _wrapper(wrapped_function, instance, args, kwargs):
         # делаем что-то до вызова функции
         result = wrapped_function(*args, **kwargs)
         # делаем что-то после вызова функции
         result = result * arg1 * arg2
         return result
    return _wrapper


def test_decorators_with_args():

    @args_decorator(2, 3)
    def func4():
        return 'We'

    @args_decorator_with_wraps(2, 2)
    def func5():
        return 'code'

    @args_decorator_with_wrapt(3, 2)
    def func6():
        return 'python'

    assert func4() == 'WeWeWeWeWeWe'
    assert func5() == 'codecodecodecode'
    assert func6() == 'pythonpythonpythonpythonpythonpython'


blog comments powered by Disqus