flask上下文全局變量,程序上下文、請求上下文、上下文鈎子 --


Flask上下文

 

Flask中有兩種上下文,程序上下文(application context)和請求上下文(request context)

當客戶端發來請求時,請求上下文就登場了。請求上下文里包含了請求的各種信息,比如請求的URL,請求的HTTP方法等。

 

上下文全局變量

視圖函數需要上下文信息,flask將請求報文封裝在request對象中,但是在視圖函數中,並沒有把它傳進視圖函數,而是直接從Flask導入一個全局的request對象,然后在視圖函數里直接調用request的屬性獲取數據。為什么在處理請求時,視圖函數里的request會自動包含對應請求的數據呢?因為flask在每個請求產生后自動激活當前請求的上下文,激活請求上下文后,request被臨時設為全局可訪問。當每個請求結束后,flask就銷毀對應的請求上下文。

 

我們在前面說request是全局對象,但這里的全局並不是實際意義上的全局。我們把這些變量理解為動態的全局變量。

 

在多線程服務中,在同一時間可能會有多個請求在處理。假設有三個客戶端同時向服務器發送請求,這時每個請求都有各自不同的請求報文,所以請求對象必然是不同的。

因此,請求對象只在各自的線程內是全局的。flask通過本地線程(thread local)技術將請求對象在特定的線程和請求中全局可訪問。

 

為了方便獲取這兩種上下文環境那種存儲的信息,flask提供了四個上下文全局變量

 

在不同的視圖函數中,request對象都表示和視圖函數對應的請求,就是當前請求(current request)。程序會有多個程序實例的情況,為了能獲取對應的程序實例,而不是固定的某一個程序實例,我們就需要使用current_app變量。

 

g存儲在程序上下文中,而程序上下文會隨着每一個請求的進入而激活,隨着每一個請求的處理完畢而銷毀,所以每次請求都會重設這個g值。

我們通常會使用它結合鈎子來保存每個請求處理前所需要的全局變量。

 

當請求進入時,flask會自動激活請求上下文,這時可以使用request和session變量。當請求上下文被激活時,程序上下文也被自動激活。

 

除了上面四個上下文變量,依賴上下文的還有url_for()和jsonify()函數,所以只能在視圖函數中使用它們。其中jsonify()函數內部調用中使用了current_app變量,url_for()則需要依賴請求上下文才可以正常運行。

 

程序上下文可以用with語句執行操作

 

程序上下文也可以顯示地使用push()方法推送(激活),在執行完操作后,用pop()方法銷毀上下文

 

請求上下文可以通過test_request_context()方法臨時創建

 

同樣的,這里也可以使用push()和pop()方法顯示地激活和銷毀上下文

 

上下文鈎子(回調函數)

flask為上下文提供了一個teardown_appcontext鈎子,使用它注冊的毀掉函數會在程序上下文被銷毀時調用,通常也在請求上下文被銷毀時調用,比如你需要在每個請求處理結束后銷毀數據庫連接:

 

@app.teardown_appcontext
def teardown_db(exception):
    db.close()

 

app.reardown_appcontext裝飾器注冊的回調函數需要接收異常對象作為參數,當請求被正常處理時這個參數將是None,這個函數的返回值將被忽略

 


免責聲明!

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



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