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也是當前這個請求的, 是徹底獨立的內存空間。瀏覽器

相關文章
相關標籤/搜索