首页 > 解决方案 > 在python中用参数组合装饰器

问题描述

我想使用一个装饰器(composer)作为参数n个装饰器,这个装饰器将用于装饰一个函数。另外我想从两个来源传递一些参数,一个在作曲家中名为“SKIP”的参数,另一个由parameter_sender装饰器发送的名为“parameter”的参数。这是我尝试过的:

def compose(*decorators, SKIP=None):
def something(func):
    @wraps(func)
    def func_wrap(parameter = None, **kwargs):
        try:
            if SKIP:
                print("I'm here")
                return func(parameter = parameter,**kwargs) 
            else:
                for decorator in reversed(decorators):
                    func = decorator(func, parameter = parameter,**kwargs) # --------- This line is providing the error ------------------
                return func
            raise exception
        except Exception as e:
            print(e)
            raise exception
    return func_wrap
return something

这是我想在哪里使用它的示例。在这个例子中,如果变量 SKIP 为真,我想跳过所有装饰器的组合。

@application.route("/function/<id_something>", methods=['GET'])
@parameter_sender
@compose(decorator_1,decorator_2, SKIP=True)
def function (id_something, **kwargs):
    try:
        #TODO:
        return jsonify("ok")
    except Exception as e:
        print(e)

但我有一个错误说:

>>I'm here
>>local variable 'func' referenced before assignment

即使 if 语句正在工作。PD:它可以在没有composer中指示的行的情况下工作。

标签: pythonflaskparameter-passingpython-decorators

解决方案


下面的代码应该做的事情。您试图从外部范围为变量设置值。在我的示例中,我使用了单独的临时变量组合。

def compose(*decorators, SKIP=None):
    def something(func):
        @wraps(func)
        def func_wrap(*args, **kwargs):
            try:
                if SKIP:
                    print("I'm here")
                    return func(*args, **kwargs)
                else:
                    composition = func
                    for decorator in reversed(decorators):
                        composition = decorator(composition)
                    return composition(*args, **kwargs)
            except Exception as e:
                print(e)
                raise
        return func_wrap
    return something

推荐阅读