在flask官方文档中有这样一段:
延迟请求回调
Flask的一个设计模式是响应对象被创建并在一系列的潜在回调函数中传递,并且可以被修改或者替换。当开始处理请求的时候,可能响应函数还不存在。响应对象可能被一个视图函数或者系统中的其它组成部份创建。
所以如果想修改响应对象但是响应对象还没有创建怎么办?
方法一:把修改响应对象的部分在after-request回调函数中事件 -- 不好
方法二:把修改响应对象的部分绑定在g中,在after-request中再运行
from flask import g
# 将回调函数绑定在g对象上 -- 作为装饰器
def after_this_request(f):
if not hasattr(g, 'after_request_callbacks'):
g.after_request_callbacks = []
g.after_request_callbacks.append(f)
return f
# 在处理请求之后会被调用,在其中执行修改响应对象的函数
@app.after_request
def call_after_request_callbacks(response):
for callback in getattr(g, 'after_request_callbacks', ()):
callback(response)
return response
不是很明白,方法一较于方法二为什么会不好?
首先你可以点击这里查看官方文档的介绍。
如果你直接把你的函数绑定在
app.after_request
上,那么每次请求之后这个函数都会被调用,你不能阻止这个函数的调用。如果你一个函数绑定在
g
上,那么因为g
的生命周期与request
是相同的,因此你的函数只和当前的request
有关。假如你在代码里加入一些判断,例如只有满足一定的条件后,才会把函数绑定到g
上,那么其他的不满足条件的request
就不会执行这个函数。上面这段代码的意思是,
after_this_request
这个函数如果调用,则会把f
绑定到g
中。上面这段代码的意思是,在每次请求后都判断一下
g
对象中是否有用户绑定的函数存在,如果有就依次调用。上面这个例子很好地阐述了在没有
response
对象的时候进行修改。可以看出,当language
为None
的时候,remember_language
函数是没有被绑定在g
对象上的,所以只有language
不是None
的请求才会执行response.set_cookie
函数。如果你把
remember_language
直接绑定在app.after_request
上,那么每次请求后这个函数都会被执行如:设计函数的一个比较好的原则,就是一个函数只做一件事。如果是这样的话,这个
remember_language
函数就会变得复杂,因为你还要访问request
对象来得到language
。