Python 将方法传递给带参数的装饰器?

Python 将方法传递给带参数的装饰器?,python,python-2.7,decorator,python-decorators,Python,Python 2.7,Decorator,Python Decorators,是否可以将带有参数的修饰方法传递给修饰器的\uuuu init\uuuu 一个简单的装饰器和使用示例 class Decorator(object): def __init__(self, *args): print args def __call__(self, func): # yep the method still have to be callable return func @Decorator def foo(): pas

是否可以将带有参数的修饰方法传递给修饰器的
\uuuu init\uuuu

一个简单的装饰器和使用示例

class Decorator(object):
    def __init__(self, *args):
        print args

    def __call__(self, func): # yep the method still have to be callable
        return func

@Decorator
def foo():
    pass

没有参数的装饰器将作为参数传递方法

$ python foo.py
(<function foo at 0x7fefd7ac1b90>,)
结果是

$ python test.py 
(1, 2, 3)

正如您所看到的,传递的参数中现在缺少该方法。

当我们将参数传递给装饰器时,我们需要创建一个额外的函数来接受这些参数,然后返回实际的装饰器:

def decorator_creator(*args):
    class Decorator(object):
        def __init__(self, func):
            print args
            print func
            self.func = func
        def __call__(self):
            return self.func()
    return Decorator

@decorator_creator(1, 2, 3)
def foo():
    pass
输出:

(1, 2, 3)
<function foo at 0x0000000002EB9EB8>
(1,2,3)

不需要内部类的替代方案:

class decorator(object):
    def __init__(self, *args):
        # This creates the decorator
        self.args = args

    def __call__(self, func):
        # This applies the decorator
        self.func = func
        return self.call

    def call(self, *moreargs):
        # And this happens when the original function is called
        print self.args, self.func, moreargs
        return self.func()

@decorator(1, 2, 3)
def foo():
    pass

我还为装饰程序使用了
functools.partial(self.method,func)
。有时很有用。

试试
@Decorator()
的例子,也许它会点击。有一个很好的描述(在我看来,这是堆栈上最好的答案之一)
@Decorator
基本上是指
foo=Decorator(foo)
。因此
@Decorator(1,2,3)
意味着
foo=Decorator(1,2,3)(foo)
Decorator(1,2,3)
应该返回一个Decorator。可能值得注意的是,在绝大多数情况下,将Decorator实现为类(即使它需要参数)是一种过火的行为,可以说代码不够清晰;一个outter闭包通常就足够了,并且可以生成更可读的代码。或者至少在decorator函数范围外定义decorator对象,然后在调用decorator时初始化并返回一个实例。只是一个小观察,这段代码不会在每次应用decorator时创建一个
decorator
类吗?@PauloBu这是必需的,因为我们在我们的类中使用了一个自由变量
args
。如果我们将类移到函数之外,那么该类将无法访问
args
。除非您将
args
参数设置为类的
\uuuuuu init\uuuuu
,并返回一个实例,这在这里似乎更有意义…@Lucas我无意中删除了
\uu调用方法,而不是修复它。
class decorator(object):
    def __init__(self, *args):
        # This creates the decorator
        self.args = args

    def __call__(self, func):
        # This applies the decorator
        self.func = func
        return self.call

    def call(self, *moreargs):
        # And this happens when the original function is called
        print self.args, self.func, moreargs
        return self.func()

@decorator(1, 2, 3)
def foo():
    pass