Flask中current_app和g對象


Flask中有兩種上下文,請求上下文和應用上下文。

請求上下文(request context)

request和session都屬於請求上下文對象。

request:封裝了HTTP請求的內容,針對的是http請求。舉例:user = request.args.get('user'),獲取的是get請求的參數。

session:用來記錄請求會話中的信息,針對的是用戶信息。舉例:session['name'] = user.id,可以記錄用戶信息。還可以通過session.get('name')獲取用戶信息。

應用上下文(application context)

current_app和g都屬於應用上下文對象。

current_app:表示當前運行程序文件的程序實例。

g:處理請求時,用於臨時存儲的對象,每次請求都會重設這個變量。比如:我們可以獲取一些臨時請求的用戶信息。

當調用app = Flask(_name_)的時候,創建了程序應用對象app;
request 在每次http請求發生時,WSGI server調用Flask.call();然后在Flask內部創建的request對象;
app的生命周期大於request和g,一個app存活期間,可能發生多次http請求,所以就會有多個request和g。
最終傳入視圖函數,通過return、redirect或render_template生成response對象,返回給客戶端。
區別: 請求上下文:保存了客戶端和服務器交互的數據。 應用上下文:在flask程序運行過程中,保存的一些配置信息,比如程序文件名、數據庫的連接、用戶信息等。

上下文對象的作用域

在flask項目中某一個功能中會有多個視圖,那么from flask import request,current_app,session,g,怎么保證某次請求的上下文不會被別的視圖拿走呢?

從pycharm中進入globals.py:

_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'))

線程有個叫做ThreadLocal的類,也就是通常實現線程隔離的類。而werkzeug自己實現了它的線程隔離類:werkzeug.local.Local。LocalStack就是用Local實現的。

LocalStack是flask定義的線程隔離的棧存儲對象,分別用來保存應用和請求上下文。
它是線程隔離的意思就是說,對於不同的線程,它們訪問這兩個對象看到的結果是不一樣的、完全隔離的。這是根據pid的不同實現的,類似於門牌號。

而每個傳給flask對象的請求,都是在不同的線程中處理,而且同一時刻每個線程只處理一個請求。所以對於每個請求來說,它們完全不用擔心自己上下文中的數據被別的請求所修改。

而這個LocalProxy 的作用就是可以根據線程/協程返回對應當前協程/線程的對象,也就是說

線程 A 往 LocalProxy 中塞入 A

線程 B 往 LocalProxy 中塞入 B


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM