python - Flask 上下文管理 流程

上下文管理:
    - 请求上下文 (ctx=RequestContext())  : request/session
    - App上下文  (app_ctx=AppContext())  : app/g

1. 请求进来执行 __call__ 方法。
2. __call__ 方法调用 wsgi_app。
3. wsgi_app:
    - (1)实例化两个方法:
    ctx = RequestContext(request,session)
    app_ctx = AppContext(app,g)
    - (2) 调用push方法(push方法实例化):
    _app_ctx_stack = LocalStack()     --> local = Local() --> __storage__ = {线程号:{stack:[app_ctx]}}
    _request_ctx_stack = LocalStack() --> local = Local() --> __storage__ = {线程号:{stack:[ctx]}}

    - PS:
        _app_ctx_stack = LocalStack() 和 _request_ctx_stack = LocalStack() 执行过程中会有:
            push(), top(), pop() 方法来维护

3.5 在这个地方可能会执行 @app.before_request 等特殊装饰器

4. 视图函数:
    - 调用 request.method  --> request = LocalProxy(partial(_lookup_req_object, 'request'))
    - 调用 session['q']    --> session = LocalProxy(partial(_lookup_req_object, 'session'))    
        - request 和 session 会调用各自的偏函数,偏函数找到 top 方法, top方法返回 ctx.request/ctx.session,
          然后偏函数会将ctx结果返回到上面两个方法中(LocalProxy), 在LocalProxy方法中再次取值(ctx.request.method/ctx.session['q']), 再将取出来的值返回到视图

    - 调用 current_app     --> current_app = LocalProxy(_find_app)
    - 调用 g                      --> g = LocalProxy(partial(_lookup_app_object, 'g'))
        - current_app 和 g 也是会调用各自的偏函数, 偏函数找到 top 方法, top方法返回 app_ctx.app/app_ctx.g,
          然后偏函数会将app_ctx结果返回到上面两个方法中(LocalProxy), 在LocalProxy方法中再次取值(app_ctx.app/app_ctx.g.xx), 再将取出来的值返回到视图

5. 视图函数处理完毕之后, 返回浏览器之前:
    - 在这个过程中, 会调用 pop() 方法:
        - ctx.pop() : 通过pop方法去到 local = Local() 中将 __storage__ = {线程号:{stack:[ctx]}} 中的 ctx删掉
        - app_ctx.pop() : 通过pop方法去到 local = Local() 中将 __storage__ = {线程号:{stack:[app_ctx]}} 中的 app_ctx删掉

5.5 在这个地方可能会执行 @app.after_request 等特殊装饰器


6. 返回给用户浏览器。


###  g 的理解 ###
概念:
    一次请求生命周期中生效的g
1. g 的生命周期:
    当有请求的时候, 就会为这个请求创建一个 g, 当这个请求结束的时候, 就会清除这个 g
        注: 有一个请求就创建一个 g, 且只能在同一个请求中使用
2.  多线程并不会影响 g, 因为每一个请求就会在 __storage__ 中创建一个唯一的线程号,
    这个线程号对应的字典中的app_ctx也是当前这个请求的, 是完全独立的内存空间。

猜你喜欢

转载自www.cnblogs.com/chaoqi/p/10508328.html
今日推荐