flask之源码解读RequestContext(请求上下文)执行流程
2018-01-05 20:30
603 查看
流程分析:
# 这里会调用Flask.__call__(self, environ, start_response) app = Flask(__name__) if __name__=='__main__': app.run() def __call__(self, environ, start_response): """Shortcut for :attr:`wsgi_app`.""" return self.wsgi_app(environ, start_response) # 接着返回一个对象,这里去执行,我们看下这个: def wsgi_app(self, environ, start_response): # 关键代码 ctx = self.request_context(environ) #返回的上下文对象放到哪里去了呢?我们看下push方法: ctx.push() # 处理请求: try: #这里去分发request,处理request finally: #当请求结束: ctx.auto_pop(error) #我们看下ctx = self.request_context(environ)做了什么? def request_context(self, environ): #返回了请求的上下文对象,那么ctx 代表请求的上下文对象 return RequestContext(self, environ) #ctx.push()调用的push方法 class RequestContext(object): def push(self): # 这里将自己加入了_request_ctx_stack, #那么_request_ctx_stack是个什么鬼? _request_ctx_stack.push(self) #在globals.py文件中可以看到: _request_ctx_stack = LocalStack() #那么LocalStack 中的都有什么呢? class LocalStack(object): def __init__(self): #接着我们看下local是个啥? self._local = Local() def push(self, obj): # push方法的作用将新的item压栈,这里看到self._local """Pushes a new item to the stack""" rv = getattr(self._local, 'stack', None) if rv is None: #现在的字典是这样的:{'当前线程的唯一标识':{'stack':[]}} self._local.stack = rv = [] # 请求进来将请求上下文RequestContext加入到列表中: rv.append(obj) return rv #接着我们看下local是个啥?self._local = Local() class Local(object): def __init__(self): # 看这是创建了空字典 object.__setattr__(self, '__storage__', {}) #这是干什么的呢?看下get_ident object.__setattr__(self, '__ident_func__', get_ident) def __setattr__(self, name, value): #触发get_ident的运行 ident = self.__ident_func__() storage = self.__storage__ try: #那么这句话构造了一个字典,key便是当前线程的标识,代表了当前线程。形如: #{'当前线程标识':{name:value}},那么回去我们再看上面:self._local.stack = rv = [] storage[ident][name] = value except KeyError: storage[ident] = {name: value} #get_ident 是干什么用的呢? def get_ident(): # real signature unknown; restored from __doc__ """ get_ident() -> integer #翻译一下:返回一个能唯一标识当前线程和其它共存线程的非零integer!!! Return a non-zero integer that uniquely identifies the current thread amongst other threads that exist simultaneously /saɪmlˈteɪniəsli/. This may be used to identify per-thread resources. Even though on some platforms threads identities may appear to be allocated consecutive numbers starting at 1, this behavior should not be relied upon, and the number should be seen purely as a magic cookie. A thread's identity may be reused for another thread after it exits. """ return 0 #当请求结束,执行ctx.auto_pop(error) def auto_pop(self, exc): if self.request.environ.get('flask._preserve_context') or \ (exc is not None and self.app.preserve_context_on_exception): self.preserved = True self._preserved_exc = exc else: # 直接将当前的请求上下文pop掉 self.pop(exc) #最终调用self.pop(exc): def pop(self, exc=_sentinel): #翻译一下:将请求上下文弹栈,并解绑! """Pops the request context and unbinds it by doing that. This will also trigger the execution of functions registered by the :meth:`~flask.Flask.teardown_request` decorator. .. versionchanged:: 0.9 Added the `exc` argument.
相关文章推荐
- flask基础之AppContext应用上下文和RequestContext请求上下文(六)
- flask之源码解读wtforms执行流程
- Flask源码解读 <2> --- 请求上下文和request对象
- Tomcat源码解读系列(三)——Tomcat对HTTP请求处理的整体流程
- struct2源码解读(11)之执行action请求中篇
- Tomcat源码解读系列三Tomcat对HTTP请求处理的整体流程
- Tomcat源码解读系列(三)——Tomcat对HTTP请求处理的整体流程
- struct2源码解读(10)之执行action请求前篇
- Alamofire源码解读系列(十二)之请求(Request)
- Tomcat源码解读系列——Tomcat对HTTP请求处理的整体流程
- flask之源码解读session处理流程
- flask之源码解读session处理流程
- Volley源码(2):执行网络请求的流程
- Tomcat源码解读系列——Tomcat对HTTP请求处理的整体流程
- Flask源码解读(2) -- context
- Flask请求处理流程(request)[待续]
- SpringMVC4.x源码分析(四):一个request请求的完整流程和各组件介绍
- Flask源码解析:Flask应用执行流程及原理
- 源码剖析.Python.深入源码剖析Flask程序请求上下文?
- Flask源码解读 <1> --- 浅谈Flask基本工作流程