装饰器错误中的Flask app.add_url_rule

时间:2014-04-14 16:25:21

标签: python flask werkzeug

我的Flask路线中有一堆装饰器,我试图压缩成一个(包括@app.route)。

我有以下@route功能:

from functools import wraps
def route(route, method):
    def decorator(f):
        print 'decorator defined'
        print 'defining route'
        app.add_url_rule(route, methods=method, view_func=f)
        print 'route defined'
        @wraps(f)
        def wrapper(*args, **kwargs):
            print 'Hello'
            # do stuff here such as authenticate, authorise, check request json/arguments etc.
            # these will get passed along with the route and method arguments above.
            return f(*args, **kwargs)
        return wrapper
    return decorator

和示例路线:

@route('/status', ['GET'])
def status():
    return Response('hi', content_type='text/plain')

路由正在定义,但wrapper()永远不会被调用,这真的很奇怪。当我将app.add_url_rule移到装饰器之外的文件末尾时,会调用wrapper();所以decorator defined语句在Flask启动时打印,Hello在我按预期点击GET /status路径时打印。

但是,如上所示,当我将app.add_url_rule放回装饰器时,decorator defined会在启动时打印,但是当我调用GET /status时,它不会打印Hello,就好像app.add_url_rule会覆盖我以某种方式定义的wrapper()函数。

为什么会这样?看起来app.add_url_route以奇怪/意想不到的方式劫持了我的功能。

如果路由被点击,我怎样才能调用wrapper(),同时在装饰器中定义app.add_url_rule

1 个答案:

答案 0 :(得分:2)

您使用Flask注册了原始函数,而不是包装器。每当路线匹配时,Flask会拨打f,而不是wrapper,因为这是您为该路线注册的内容。

告诉Flask在路线匹配时拨打wrapper,而不是:

def route(route, method):
    def decorator(f):
        print 'decorator defined'
        print 'defining route'
        @wraps(f)
        def wrapper(*args, **kwargs):
            print 'Hello'
            # do stuff here such as authenticate, authorise, check request json/arguments etc.
            # these will get passed along with the route and method arguments above.
            return f(*args, **kwargs)

        app.add_url_rule(route, methods=method, view_func=wrapper)
        print 'route defined'
        return wrapper
    return decorator