• 请求上下文


    源码粗略分析

    '''
    globals:
        _request_ctx_stack = LocalStack()
        _app_ctx_stack = LocalStack()
        current_app = LocalProxy(_find_app)
        request = LocalProxy(partial(_lookup_req_object, "request"))
        session = LocalProxy(partial(_lookup_req_object, "session"))
        g = LocalProxy(partial(_lookup_app_object, "g"))
    
    1  run_simple(host, port, self, **options),self是app,执行self(),Flask里面的__call__
    
    2 在__call__里面执行的return self.wsgi_app(environ, start_response),把执行结果返回,
        environ请求相关的, start_response响应相关的
    
    3 self.wsgi_app(environ, start_response)的源码:
            def wsgi_app(self, environ, start_response):  
                #得到一个RequestContext的对象,这对象里面有包含了request和session       
                ctx = self.request_context(environ)
                error = None
                try:
                    try:                  
                        ctx.push()
                        response = self.full_dispatch_request()
                    except Exception as e:
                        error = e
                        response = self.handle_exception(e)
                    except:  # noqa: B001
                        error = sys.exc_info()[1]
                        raise
                    return response(environ, start_response)
                finally:
                    if self.should_ignore_error(error):
                        error = None
                    ctx.auto_pop(error)
                    
            3.1 执行 ctx = self.request_context(environ):environ请求相关的:的源码
                    return RequestContext(self, environ) self是app,environ请求相关的
                    3.1.1RequestContext(self, environ)实例化一个RequestContext对象
                            def __init__(self, app, environ, request=None, session=None):
                                self.app = app
                                if request is None:
                                    request = app.request_class(environ)
                                self.request = request
                                self.url_adapter = None
                                try:
                                    self.url_adapter = app.create_url_adapter(self.request)
                                except HTTPException as e:
                                    self.request.routing_exception = e
                                self.flashes = None
                                self.session = session
                3.1总结:ctx = self.request_context(environ)以后ctx为RequestContext对象,这个对象有request,session
            
            3.2   ctx.push()里面执行了
                    _request_ctx_stack.push(self):self是ctx
                3.2.1_request_ctx_stack这个是一个全局变量是LocalStack()的对象
                    _request_ctx_stack.push(self)就是执行LocalStack里面的push方法
                    
                    3.2.1.1 LocalStack里面的push方法,obj参数是ctx
                            def push(self, obj):
                                rv = getattr(self._local, "stack", None)
                                if rv is None:
                                    self._local.stack = rv = []
                                #把obj,也就是ctx存到了LOCAL对象中的storage,存的格式为: storage={"执行id":{'stack':[ctx,]}}
                                rv.append(obj)
                                return rv
                    3.2.1.2 rv = getattr(self._local, "stack", None)这个self._local是LOCAL对象
                    
            3.3 response = self.full_dispatch_request(),这里是响应函数与请求扩展
                    def full_dispatch_request(self):
                        #第一请求的函数,before_first_request里面的所有函数
                        self.try_trigger_before_first_request_functions()
                        try:
                            #信号
                            request_started.send(self)
                            #before_request执行的结果,如果这个里面有返回值,后面的befor_request都不会执行
                            #如果 rv = self.preprocess_request(),rv为None,才会执行self.dispatch_request()
                            #也就响应函数
                            rv = self.preprocess_request()
                            if rv is None:
                                # 真正的响应函数,如果上面的before_request没有返回值就执行它,并拿到rv这个返回值
                                rv = self.dispatch_request()
                        except Exception as e:
                            rv = self.handle_user_exception(e)
                        #请求之后的函数,也就是after_request的函数
                        return self.finalize_request(rv)
                
            
            3.4 请求结束后执行ctx.auto_pop(error)把它在LOCAL对象中删除.删除的是ctx
    
  • 相关阅读:
    ABP WebApi的请求类型
    对服务器的文件或文件夹压缩
    VS运行遇到的那些坑
    asp.net core Api集成Swagger
    通过文件路径获取文件名
    读取服务器或者本地的文件夹下面的文件
    计算出 3 至 1000 范围内最大的十个素数,放入数组中,并计算出其累加和。
    LINUX 无法登入系统(2017-1-16)
    zynq里面的AXI总线(2017-1-11)
    学习随笔(2017-1-10)
  • 原文地址:https://www.cnblogs.com/chanyuli/p/12153152.html
Copyright © 2020-2023  润新知