我的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
?
答案 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