Flask 函数装饰器 运行 在定义时和调用时?

Flask function decorator run at defintion time and call time?

我正在尝试在 Flask 中实现一个装饰器函数,它做两件事:注册页面路由并在定义时向我的数据库添加一些内容,然后在运行时向页面发出请求时向它添加一些内容处理用户是否通过身份验证。

我知道我可以在两个单独的装饰器函数中执行这些操作,但这行不通,因为我最终需要在两个定义时处理同一组信息(应用程序、规则、访问组等)和运行时间。

下面的代码是我一直在弄乱的代码,但我无法让它工作。它会编译,您可以在控制台中看到 "Definition time" 并在浏览器中看到 "index",但是 "Runtime" 永远不会被打印出来。谁能指出我可能做错了什么?

from flask import Flask
from functools import wraps

app = Flask(__name__)


def register(app, rule, **options):
    def wrapper(f):
        print "Definition time"
        endpoint = options.pop('endpoint', f.__name__)
        access_groups = options.pop('access_groups', None)
        methods = options.get('methods', ['GET'])

        app.add_url_rule(rule, endpoint, f, **options)

        @wraps(f)
        def wrapped(*args, **kwargs):
            print "Runtime"
            return f(*args, **kwargs)
        return wrapped

    return wrapper


@register(app, '/', methods=['GET', 'POST'], access_groups=['all-access'])
def index():
    return "index"

if __name__ == '__main__':
    app.run(debug=True)

您在 add_url_rule 中添加了原始函数,而不是包装函数。将 add_url_rule 移动到 wrapped 下方并更改目标。

def wrapped(...)
    ...

app.add_url_rule(rule, endpoint, wrapped, **options)
return wrapped

这是完整的代码和 运行 访问时控制台上的输出。

from functools import wraps
from flask import Flask

app = Flask(__name__)

def register(app, rule, **options):
    def wrapper(f):
        print('Definition time')
        endpoint = options.pop('endpoint', f.__name__)
        access_groups = options.pop('access_groups', None)
        methods = options.pop('methods', ['GET'])

        @wraps(f)
        def wrapped(*args, **kwargs):
            print('Runtime')
            return f(*args, **kwargs)

        app.add_url_rule(rule, endpoint, wrapped, **options)
        return wrapped

    return wrapper

@register(app, '/', methods=['GET', 'POST'], access_groups=['all-access'])
def index():
    return 'index'

if __name__ == '__main__':
    app.run(debug=True)
$ python example.py 
Definition time
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
Runtime
127.0.0.1 - - [04/Aug/2015 20:14:46] "GET / HTTP/1.1" 200 -