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