详解flask上下文与出入栈

在flask中,上下文算是核心中的核心了,其作用于请求的访问处理,多线程隔离的实现等。

flask的上下文:

1、应用上下文 (AppContent)
2、请求上下文 (Request Context)

如图所示:
20180506181132_533.jpg

应用上下文是对当前应用实例app的封装
请求上下文是对当前请求Request的封装

1、当每一个请求进入系统的时候,都会将当前的应用上下文和请求上下文进行入栈操作,所代表的栈对象分别是_app_ctx_stack和_request_ctx_stack。
2、栈对象进入栈顶的顺序是,先应用上下文的栈对象先进入栈顶,然后才是请求上下文的栈对象进入栈顶

注意:

1、当一个请求进来时,也就是在请求的逻辑中要获取应用上下文,flask会先判断应用上下文的栈顶是否有该应用实例栈对象,没有的话会自动帮着将当前的应用上下文栈对象推入栈中。也就是说,在请求的逻辑视图处理中,是可以获取到当前的应用上下文的。
2、通过current_app和request获取当前应用上下文和请求上下文,其实都是经过了flask的封装,该方法是localproxy,都是分别去各自的栈顶获取栈对象,然后再取出app和request这个属性。

3、在不是请求视图中要获取当前的应用上下文,是需要自己将当前的应用栈对象push到栈中的,然后才能通过current_app来获取到当前应用实例。通常在离线应用和单元测试场景上会使用到。
具体代码如下:

app = Flask(__name__)

ctx = app.app_content()
ctx.push()

然后使用完了需要将其在栈中去除
ctx.pop()

所有名词解释

1、以线程ID号作为key的字典->Local->LocalStack
(local是通过点来实现线程隔离的,localstack则是封装了local通过push()、pop()和top成为线程隔离对象(栈))
2、AppContext RequestContext -> LocalStack
(AppContext是应用上下文,RequestContext是请求上下文,分别依次推入各自的线程隔离对象中)
3、Flask -> AppContext Request -> RequestContext
(AppContext封装的是Flask的应用核心对象,RequestContext封装的是本次请求的Request对象)
4、current_app ->(LocalStack.top = AppContext top.app=Flask)
(current_app指的是线程隔离对象栈顶的元素(应用上下文)的app属性(核心对象))
5、request ->(LocalStack.top = RequestContext top.request= Request)
(request指的是线程隔离对象栈顶元素(请求上下文)的request属性(当前request对象))

注意:app,也就是当前应用核心对象只有一个,因为它是在主线程中生成的,而request则是每次请求都会生成一个,所以需要线程隔离。app的话,因为作为字典存在的线程隔离,都是同一个value是没有意义的,所以app并没有被线程隔离

Last modification:November 25th, 2019 at 10:47 pm
如果觉得我的文章对你有用,请随意赞赏

Leave a Comment