请求上下文源码分析
一、请求上下文源码
第一阶段:将ctx(request,session)放到Local对象上 第二阶段:视图函数导入:request/session request.method -LocalProxy对象.method,执行getattr方法,getattr(self._get_current_object(), name) -self._get_current_object()返回return self.__local(),self.__local(),在LocakProxy实例化的时候,object.__setattr__(self, '_LocalProxy__local', local),此处local就是:partial(_lookup_req_object, 'request') -def _lookup_req_object(name): top = _request_ctx_stack.top #_request_ctx_stack 就是LocalStack()对象,top方法把ctx取出来 if top is None: raise RuntimeError(_request_ctx_err_msg) return getattr(top, name)#获取ctx中的request或session对象 第三阶段:请求处理完毕 - 获取session并保存到cookie - 将ctx删除
二、总结
-请求来了app()执行---》执行Flask类的__call__方法,内部执行self.wsgi_app(environ, start_response) -wsgi_app(environ, start_response) -ctx = self.request_context(environ):返回一个RequestContext类的对象,传入了env和app,对象内部有:app,request,session.. -ctx.push(): 调用了 _request_ctx_stack.push(self),_request_ctx_stack:是LocalStack对象(内部有个local) 调用了LocalStack的push方法,传入了ctx(app,request,session..), 把ctx放到了LocalStack内的local对象上,处理了线程安全,数据结构是 { '线程id号':{stack:[ctx,]} '线程id号2':{stack:[]} } 执行视图函数 -print(request)--->执行request(LocalProxy)对象的__str__方法 -问题:LocalProxy是什么时候初始化的?程序一执行就初始化了request = LocalProxy(partial(_lookup_req_object, "request")) -问题:request.method --->LocalProxy.__getattr__ 他通过反射去当前线程下的request中取出了method -结束