16Flask请求上下文源码解析

Flask请求上下文源码解析

from  flask import Flask,request

app=Flask(__name__)

@app.route("/")
def index():
    print(request.form)

    return "1"



if __name__ == '__main__':
    #self,是app,app(),--->Flask对象,Flask的__call__
    app.__call__
    app.run()


'''
1     app.__call__
2     wsgi_app(environ, start_response) 
2.1 ctx = self.request_context(environ)
    2.1.1 return RequestContext(self, environ)
        这里的self是app,environ请求相关
    2.1.2 return RequestContext(self, environ)
    得到了RequestContext的对象,而且有request属性
2.2  2.1中的ctx就是RequestContext的对象  

2.3  ctx.push()执行这个,就是RequestContext的对象的push方法
     2.3.1  #执行这个,self-->ctx
        _request_ctx_stack.push(self) 
        2.3.1.1 我们发现_request_ctx_stack = LocalStack()
        他的push方法的源码:
                def push(self, obj):
                    rv = getattr(self._local, "stack", None)
                    if rv is None:     
                        # self._local=>stack-->storage['线程id']['stack']=[ctx,]
                        self._local.stack = rv = []
                    rv.append(obj)
                    return rv
                    
3在请求中获取request.form
3.1 request是LocalProxy的对象,当获取属性的时候会走__getattr__
    def __getattr__(self, name):
        if name == "__members__":
            return dir(self._get_current_object())
        #name-->form,
        #self._get_current_object()===>ctx.request,form
        #_get_current_object()---》self.__local()
        
        return getattr(self._get_current_object(), name)
        
    3.1.1 self._get_current_object():源码:最终:partial(_lookup_req_object, "request")
     def _get_current_object(self):
     
        if not hasattr(self.__local, "__release_local__"):
                #local==>partial(_lookup_req_object, "request")
                #def __init__(self, local, name=None):
                    # object.__setattr__(self, "_LocalProxy__local", local)
            #self.__local()===>local()
            return self.__local()
        try:
            return getattr(self.__local, self.__name__)
        except AttributeError:
            raise RuntimeError("no object bound to %s" % self.__name__)
4 partial(_lookup_req_object, "request")偏函数的源码
    def _lookup_req_object(name):
        #name是request
        #ctx
        top = _request_ctx_stack.top
        if top is None:
            raise RuntimeError(_request_ctx_err_msg)
        #ctx-->request
        return getattr(top, name)
    4.1中_request_ctx_stack.top
       @property
        def top(self):
        
        try:
            return self._local.stack[-1]
        except (AttributeError, IndexError):
            return None


'''
posted @ 2019-12-01 15:10  suren_apan  阅读(75)  评论(0编辑  收藏  举报