简体   繁体   中英

Composing decorator with parameters in python

I want to use a decorator ( composer ) that recevices as parameter n number of decorators, this decorators will be used to decorate a function. Also I want to pass some parameters from two origins, a parameter named "SKIP" in the composer and another parameter named "parameter" sent by the parameter_sender decorator. Here's what I tried:

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

And here is an example of where do I want to use it. In this example I want to SKIP the composing of all the decorators if the variable SKIP is true.

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

But i've got an error that says this:

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

Even when the if statement is working. PD: It works without the line indicated in the composer .

The following code should do the thing. You were trying to set a value for a variable from outer scope. In my example I used separate temp variable composition.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM