使用参数将方法传递给装饰器?

时间:2014-03-27 21:41:00

标签: python python-2.7 decorator python-decorators

是否可以将装饰方法参数传递给装饰器的__init__

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

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>,)

当我向装饰器添加参数时

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

导致

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

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

2 个答案:

答案 0 :(得分:4)

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

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)

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

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)作为装饰者。有时很有用。