Flask中有两种上下文,程序上下文(application context)和请求上下文(request context)数据库
当客户端发来请求时,请求上下文就登场了。请求上下文里包含了请求的各类信息,好比请求的URL,请求的HTTP方法等。json
视图函数须要上下文信息,flask将请求报文封装在request对象中,可是在视图函数中,并无把它传进视图函数,而是直接从Flask导入一个全局的request对象,而后在视图函数里直接调用request的属性获取数据。为何在处理请求时,视图函数里的request会自动包含对应请求的数据呢?由于flask在每一个请求产生后自动激活当前请求的上下文,激活请求上下文后,request被临时设为全局可访问。当每一个请求结束后,flask就销毁对应的请求上下文。flask
咱们在前面说request是全局对象,但这里的全局并非实际意义上的全局。咱们把这些变量理解为动态的全局变量。服务器
在多线程服务中,在同一时间可能会有多个请求在处理。假设有三个客户端同时向服务器发送请求,这时每一个请求都有各自不一样的请求报文,因此请求对象必然是不一样的。session
所以,请求对象只在各自的线程内是全局的。flask经过本地线程(thread local)技术将请求对象在特定的线程和请求中全局可访问。多线程
为了方便获取这两种上下文环境那种存储的信息,flask提供了四个上下文全局变量app
在不一样的视图函数中,request对象都表示和视图函数对应的请求,就是当前请求(current request)。程序会有多个程序实例的状况,为了能获取对应的程序实例,而不是固定的某一个程序实例,咱们就须要使用current_app变量。函数
g存储在程序上下文中,而程序上下文会随着每个请求的进入而激活,随着每个请求的处理完毕而销毁,因此每次请求都会重设这个g值。url
咱们一般会使用它结合钩子来保存每一个请求处理前所须要的全局变量。spa
当请求进入时,flask会自动激活请求上下文,这时可使用request和session变量。当请求上下文被激活时,程序上下文也被自动激活。
除了上面四个上下文变量,依赖上下文的还有url_for()和jsonify()函数,因此只能在视图函数中使用它们。其中jsonify()函数内部调用中使用了current_app变量,url_for()则须要依赖请求上下文才能够正常运行。
一样的,这里也可使用push()和pop()方法显示地激活和销毁上下文
flask为上下文提供了一个teardown_appcontext钩子,使用它注册的毁掉函数会在程序上下文被销毁时调用,一般也在请求上下文被销毁时调用,好比你须要在每一个请求处理结束后销毁数据库链接:
@app.teardown_appcontext
def teardown_db(exception):
db.close()
app.reardown_appcontext装饰器注册的回调函数须要接收异常对象做为参数,当请求被正常处理时这个参数将是None,这个函数的返回值将被忽略