Как переключать декораторы с аргументами? - PullRequest
0 голосов
/ 10 июня 2019

Мне нужен декоратор, который собирает статистику использования для данной функции, но также может динамически переключаться в коде.Я нашел пример SO - переключения декораторов

import functools

class SwitchedDecorator:
    def __init__(self, enabled_func):
        self._enabled = False
        self._enabled_func = enabled_func

    @property
    def enabled(self):
        return self._enabled

    @enabled.setter
    def enabled(self, new_value):
        if not isinstance(new_value, bool):
            raise ValueError("enabled can only be set to a boolean value")
        self._enabled = new_value

    def __call__(self, target):
        if self._enabled:
            return self._enabled_func(target)
        return target


def deco_func(target):
    """This is the actual decorator function.  It's written just like any other decorator."""
    def g(*args,**kwargs):
        print("your function has been wrapped")
        return target(*args,**kwargs)
    functools.update_wrapper(g, target)
    return g


# This is where we wrap our decorator in the SwitchedDecorator class.
my_decorator = SwitchedDecorator(deco_func)

# Now my_decorator functions just like the deco_func decorator,
# EXCEPT that we can turn it on and off.
my_decorator.enabled=True

@my_decorator
def example1():
    print("example1 function")

# we'll now disable my_decorator.  Any subsequent uses will not
# actually decorate the target function.
my_decorator.enabled=False
@my_decorator
def example2():
    print("example2 function")

Это работает для декоратора без каких-либо аргументов, но мне нужен декоратор, который также имеет аргументы.Я посмотрел примеры его создания, но не смог найти решение, которое подходит для этой модели.В основном, есть свойство enable, которое предоставляет этот пример, но также есть возможность передавать аргументы.Я создал deco_func(), который может иметь аргументы

def decoratorFunctionWithArguments(arg1, arg2):
    def wrap(f):
        print "Inside wrap()"
        def wrapped_f(*args):
            print "Inside wrapped_f()"
            print "Decorator arguments:", arg1, arg2
            f(*args)
            print "After f(*args)"
        return wrapped_f

    return wrap

Но я не могу передать это SwitchedDecorator, так как он жалуется на аргументы в функции __call__.

...