flask的上下文管理

请求到来时:
app是Flask对象
先执行app的call方法 -- wsgi_app方法
1、- wsgi_app方法会调用app的request_context方法,返回ctx
  返回RequestContext对象ctx,参数是app和environ,environ就是请求的所有内容
  - 1.1执行RequestContext的init方法
    封装ctx.app就是Flask对象,封装ctx.request就是Request对象,这里面就是请求的所有内容
    还有封装flash和session
2、- wsgi_app方法会继续调用ctx的push方法
  - 2.1执行RequestContext对象的push方法,参数是ctx
  - 2.2会先执行一些东西,但是没有讲,继而执行_request_ctx_stack的push方法,参数还是ctx
    _request_ctx_stack是LocalStack对象,执行LocalStack的push方法,参数还是ctx
    会给_request_ctx_stack对象的_local属性(local对象)封装stack属性值为空列表,将ctx追加进去
2.3执行Local对象的setattr方法(_request_ctx_stack._local),key就是线程或协程的唯一标识,value值是一个字典
  这个字典中的key就是stack,value值是带有ctx的列表,也就是给_request_ctx_stack._local属性值的__storage__属性添加键值对
3、- 最后执行ctx的auto_pop方法
  3.1执行RequestContext的auto_pop方法,会调用ctx的pop方法
    在ctx的pop方法中会调用_request_ctx_stack(localstack对象)的pop方法
    在localstack的pop方法中会找到stack属性对应的列表并删掉,也就是把当前线程或协程对应的RequestContext对象ctx删掉





请求到来之前:
0实例化LocalStack对象_request_ctx_stack
  0.1执行LocalStack的init方法
    封装_request_ctx_stack._local属性,属性值是Local对象
  0.2执行Local的init方法
    封装_request_ctx_stack._local.__storage__属性值是空字典
    封装_request_ctx_stack._local.__ident_func__属性值是线程或协程的唯一标识
    Local类就是专门来保存每个线程特有的值
1实例化LocalProxy对象request
  1.1执行LocalProxy的init方法
    封装_LocalProxy__local属性就是偏函数partial(_lookup_req_object, 'request')

 

视图中对request进行处理
打印request
1执行request的__str__方法
  1.1在LocalProxy的__str__方法中会调用request的_get_current_object方法
  1.2在这个方法中就会调用偏函数执行
  1.3偏函数中会调用_request_ctx_stack的top方法
    top方法就会获取stack属性值也就是列表,取索引-1,也就是当前线程或协程对应的RequestContext对象
    并且获取这个RequestContext对象的request属性值,也就是之前二次封装的Request对象,保存当前请求的所有内容

打印request.method
2执行request的getattr方法
  2.1在LocalProxy的getattr中,还是会调用equest的_get_current_object
  2.2调用偏函数
  2.3偏函数中会调用_request_ctx_stack的top方法,返回Request对象
    回到LocalProxy的getattr中获取这个Request对象的method属性值
  2.4去Request对象中找method属性值

 

 

 

 

posted @ 2018-03-26 20:47  九二零  阅读(92)  评论(0编辑  收藏  举报