2016-10-10 43 views
1

我有一种情况,如:传播参数来装饰它结合了其他装饰

@decorator_one(1) 
@foo 
@bar 
def my_decorated_func(): 
    pass 

我试图凝结成是这样的:

@my_custom_decorator(1) 
def my_decorated_func(): 
    pass 

这是简单的,如果我有一个做装饰没有(1)选项:

def my_custom_decorator(f): 
    @decorator_one 
    @foo 
    @bar 
    def wrapped(): 
     pass 
    return wrapped 

但是我不确定如何公关将参数传播给第一个包装器。

在这种情况下,我很自在地假设,如果我将1传递给my_custom_decorator,它将始终只是decorator_one的arg。

回答

4

@decorator_one(1)表示存在可返回装饰器的可调用对象;称它为装饰者工厂decorator_one(1)返回应用于该函数的装饰器。

上的争论只是通过从自己的装饰厂:

def my_custom_decorator(*args, **kwargs): # the factory 
    def decorator(f):      # the decorator 
     @decorator_one(*args, **kwargs) 
     @foo 
     @bar 
     def wrapped(): 
      pass 
     return wrapped 
    return decorator 

我以前*args, **kwargs对任意参数传递给包裹装饰厂decorator_one(),但你也可以使用显式命名PARAMATERS。

0

是的,你需要一个装饰工厂。

我找到了解决方案使用一类更有吸引力,因为它的工厂和装饰分离:

class my_custom_decorator(object): 

    __init__(self, *args, **kwargs): # the factory 
     self.args = args 
     self.kwargs = kwargs 

    __call__(self, f): # the decorator 
     @decorator_one(*self.args, **self.kwargs) 
     @foo 
     @bar 
     def wrapped(): 
      pass 

     return wrapped