对Flask上下文的理解,从working outside application context错误说起

Flask提供了2种上下文,请求上下文和应用上下文,其本质就是对Request和Flask的封装,并将其封装成RequestContext类和AppContext类。
当你在一个没有上下文环境的模块中,直接引入request和current_app并且直接使用它时,会报错:working outside application context,这是一个典型的错误,当去调试时会发现:在这里插入图片描述是说这是一个未绑定的本地代理。
分析源码,发现都会有一个push、pop方法,看这个图:
对Flask上下文的理解,从working outside application context错误说起_第1张图片
过程:当一个请求进入flask框架,先会去实例化一个RequestContext,封装了这次请求的相关信息,在生成请求上下文后,会把请求上下文推入(push)到栈(LocalStack)中,LocalStack实例化后存储到_request_ctx_stack中,在RequestContext入栈之前,会去检查LocalStack的另外一个实例化_app_ctx_stack的栈,其栈顶元素是否为空或者不是当前对象,若为空或者不是当前对象,会先将AppContext推入(push)到_app_ctx_stack中,再去将RequestContext入栈。LocalProxy中current_app和request分别指向_app_ctx_stack和_request_ctx_stack的栈顶,只有当栈顶元素为空时,LocalProxy才会才会出现unbounding现象。
综上,working outside application context这个问题就得解了,是因为栈顶元素为空,解 决方法是手动将上下文加入到栈中:
ctx = app.app_context()(获取到上下文)
ctx.push()
a = current_app(此时a就不会报working outside application context错误了)
当请求结束时,两个栈中的元素会被弹出(POP)
在编写离线应用或者单元测试的时候需要手动将AppContext入栈。而一般的web应用程序不需要,因为每一个web应用程序都是会发起一个请求的,而不是独立的,在之前,会进行一个逻辑判断,若app_ctx_stack栈顶为空或者不是当前对象,会自动入栈,所以不会出现这种情况,但若是单独发起的,可能会存在。

你可能感兴趣的:(菜鸟,IT程序媛,编程爱好者)