全局对象request解析
由源代码布局可知,globals.py保存flask的全局对象,包括
1. current_app
2. request
3. g
我们首先来讲讲request对象:
源码:
from functools import partial
from werkzeug.local import LocalProxy
from werkzeug.local import LocalStack
def _lookup_req_object(name):
top = _request_ctx_stack.top
if top is None:
raise RuntimeError(_request_ctx_err_msg)
return getattr(top, name)
_request_ctx_stack = LocalStack()
request = LocalProxy(partial(_lookup_req_object, "request"))由代码可知,request的实现主要依赖于LocalProxy和LocalStack,简单说一说LocalProxy和LocalStack:
LocalProxy:werkzeug实现的一种代理对象,可知实现被代理对象的动态更新。LocalStack:LocalStack是werkzeug库实现的栈,对象压入的规则简单总结为先入后出,并且可以方便的访问栈顶对象以及各种常用操作,比如push、pop等。
werkzeug实现的具体细节,感兴趣的同学可以翻看源码,后续我们也会一起来看。
接下来,看一下request的对象的具体的工作原理和生命周期:
生命周期:
request的对象的进栈和出栈的逻辑都在Flask类的wsgi_app方法中进行的,我们来看一下:
由代码可知,当http请求到达时,flask先通过environ参数构造RequestContext对象ctx,然后调用ctx.push(),在请求处理完毕后调用ctx.auto_pop(error),整个请求流程就结束了,request的进栈和出栈也同时完成。
接下来看看RequestContext的push方法,到底做了什么操作:
由push方法可知,此时不仅进行reqeuest的入栈操作,同时进行app对象的入栈操作,这样我导入from flask import request,就可以保障_request_ctx_stack的栈顶是当前请求信息构造的request对象,方便我们对请求信息的读取,并在处理完毕后,进行pop操作,清理_request_ctx_stack,等待下次请求的到达。
工作原理
由全局变量的逻辑可知,request本质是RequestContext实例的request属性,而RequestContext实例的request属性是Flask类的request_class属性,即Request类,综合而看request就是Request类实例化对象。而Request有多个父类,包含以下种类:
JSONMinxin
AcceptMixin
ETagRequestMixin
UserAgentMixin
AuthorizationMixin
CORSRequestMixin
CommonRequestDescriptorsMixin
这样request实例就被赋予多种属性与方法,方便在调用时访问当前http请求的各种信息。
Last updated
Was this helpful?