带Flask的装饰器

时间:2019-01-04 02:42:32

标签: python flask decorator python-decorators

我正在尝试创建带有参数的装饰器,并将其与flask模块一起使用。

def ios_network_access(arg): #TODO: 
    def real_ios_network_access_decorator(fn):
        def ios_network_access_inner():
            if not request.json:
                print("aborting because not json", fn.__name__)
                abort(400)
            try: 
                print("check args", arg)
                return fn()
            except Exception as e:
                print("the following error occurred in:", fn.__name__)
                print(request.json)
                print(str(e))
                print("---------------------------------")
                abort(503)
   return real_ios_network_access_decorator
@app.route("/someurl")
@ios_network_access("some argument")
def some_function_for_url():
    pass

但是,由于flask在其装饰器中使用了函数名称(烧瓶需要函数名称的唯一性,并且装饰器将其屏蔽),所以未创建我的端点。

这里有一个非常相似的问题,询问非参数化装饰器。但是,由于增加了功能层,这个问题有所不同。参见AssertionError: View function mapping is overwriting an existing endpoint function: main

有没有关于如何根据烧瓶的qwerks将参数传递给装饰器的想法?

1 个答案:

答案 0 :(得分:1)

wraps函数是包装装饰器函数的便捷方法。 包装函数的属性会使用原始函数中的相应属性进行更新。

from functools import wraps

def ios_network_access(arg):
    def real_ios_network_access_decorator(fn):
        @wraps(fn)
        def ios_network_access_inner(*args, **kwds):
            if not request.json:
                print("aborting because not json", fn.__name__)
                abort(400)
            try: 
                print("check args", arg)
                return fn(*args, **kwds)
            except Exception as e:
                print("the following error occurred in:", fn.__name__)
                print(request.json)
                print(str(e))
                print("---------------------------------")
                abort(503)
        return ios_network_access_inner
    return real_ios_network_access_decorator