我回答下我的思考:
比如部署Flask的时候是多进程部署,每个进程内部又是多线程的Flask监听HTTP请求。
当任何一个请求进入,就会被分配到某个进程的某个线程执行(7月老师讲线程和进程,进程负责执行,没毛病)。
该线程,在该Flask App进程下,就会通过 线程id识别,在 request的栈里,塞入一个对象。这里说是栈结构,实际上这是一个 字典结构,保证彼此隔离,之所以用栈去表达,是想表达保存的意思吧,实际上是用字典;你可以想想下,站在总进程的角度来看,不同线程逐个接收到请求,字典逐个被压入对象,仿佛一个栈,不断地被压入对象。
request的请求,会主动让 app_context_stack压入对应 线程id的一个 flask app实例。
然后你在 g,app_context_stack, request_stack, session 中能够看到,都是字典,他们通过相同的 线程id,保存着对应的对象。访问的时候,都是彼此对应的,当请求解除,也被依次对应的销毁掉。
这里巧妙的地方在于,利用一个字典结构:
简化了书写,不需要每个view函数都接收四个对象
过程变得优雅
Flask作者聪明的利用这个设计,把事情变得优雅又简单。这就是他为啥用这个的理由。也是Flask的技术亮点。
上面是个人的一点思考,这里如果有解释不对的,希望各位同学指正。