哈嘍大家好,我是鹹魚。今天我們來聊聊什麼是 Flask 上下文
鹹魚在剛接觸到這個概念的時候腦子裡蹦出的第一個詞是 CPU 上下文
今天鹹魚希望透過這篇文章,讓大家能夠對 Flask 上下文設計的初衷以及應用有一個基本的瞭解
Flask 上下文
我們在使用 Flask 開發 web 程式的時候,通常會面臨下面的情況
假設同一時間內有三臺客戶端(或瀏覽器)向 web 伺服器傳送了請求,那麼 Flask 應用是如何分辨出這三個請求屬於哪臺客戶端(或瀏覽器)並返回正確的響應的呢?
聰明的你結合文章題目很快就想到了——Flask 上下文
在 Flask 中,透過本地執行緒技術來實現上下文隔離。本地執行緒是一種輕量級的執行緒,它可以在同一個程式中建立多個執行緒,並且每個執行緒擁有獨立的堆疊和暫存器等資源,因此可以併發地執行多個任務
1、接收到請求的時候,Flask 會為每個請求建立一個 Flask 上下文物件,這個上下文物件包含了一些全域性或者請求級別的變數
2、處理請求的時候,Flask 會為這個請求的上下文物件分配或建立一個本地執行緒,這樣就可以在處理請求的各個環節當中透過本地執行緒來訪問這個請求的上下文物件了
3、請求處理完畢之後,Flask 會將請求上下文物件從當前執行緒中刪除並銷燬。這樣就能保證每次請求都是獨立的,避免了執行緒安全問題
結合上面的例子我們得知,首先 Flask 應用會為這三個請求分配(或建立)到不同的執行緒中,然後建立與三個請求對應的三個 Flask 上下文物件(應用上下文和請求上下文)並儲存到本地執行緒當中
到這裡有小夥伴可能會問,Flask 應用是如何區分這三個請求上下文的呢?
Flask 使用的上下文是透過 werkzeug.local
模組中的 Local
類實現的。Local
物件實際上是一個字典,它的鍵是執行緒 ID,值是該執行緒對應的上下文物件
所以說,Flask 透過執行緒 ID 來區分不同的請求上下文
兩種上下文
現在我們知道了,Flask 會自動為每個請求建立一個專屬的獨一無二的環境,稱為上下文
這個上下文環境包含了一些全域性級別和請求級別的變數,可以在請求處理的整個過程當中使用
也就是說,Flask 上下文由兩部分組成——應用上下文和請求上下文
應用上下文(application context)
當一個 Flask 應用啟動時,會自動建立一個應用上下文物件。這個應用上下文物件表示整個應用的執行環境,用於儲存應用全域性的變數和配置(應用配置、資料庫連線資訊等)
對於每個請求來說,應用上下文物件會在當前請求處理之前建立,並且會一直存在到請求處理完畢之後才被銷燬。這意味著,應用上下文物件可以在整個請求生命週期內共享資料
請求上下文(request context)
當請求到達 Flask 應用的時候,每一個請求都會有一個專屬的請求上下文環境,用於儲存請求相關的變數和資訊(請求路徑、請求方法、請求引數等等)
應用上下文和請求上下文的區別
可以看到,應用上下文是全域性的,表示整個 Flask 應用的執行環境,而請求上下文是針對每個請求獨立的,表示該請求的執行環境
在應用程式的整個生命週期中,應用上下文只有一個,而且存在於應用的整個生命週期中。而請求上下文會隨著請求的到來而動態建立和銷燬
對於每個請求來講,應用上下文是每個請求共享的,請求上下文是每個請求獨有的
舉個簡單的例子,比如說有一家大型超市(Flask 應用),每當有顧客來超市買東西的時候(相當於請求到達 Flask 應用),店員就會為每個顧客分配一個購物車(本地執行緒)
這個購物車裡面存放了每個顧客的商品、折扣券(請求上下文)等等。購物車裡面的東西是每個顧客專屬的、獨有的(不同請求的請求上下文是獨立的)
當顧客消費完畢之後,購物車裡面的東西就會清空,店員就會回收這些購物車,等待分配給下一個顧客使用(請求處理完畢之後將請求上下文物件從當前執行緒中刪除並銷燬,並後續為新到的請求分配執行緒)
而這個超市裡面的電梯、貨架以及商品(應用上下文)都是每個顧客共享的(應用上下文是每個請求共享的)
當超市關門的時候,電梯、貨架以及商品就不能夠對外使用了(應用上下文存在於應用的生命週期中)
Flask 上下文啟用
Flask 上下文可以分為自動啟用和手動啟用兩種方式
自動啟用
自動啟用是指 Flask 在處理請求時自動啟用應用上下文和請求上下文,無需手動干預,這樣可以避免在程式碼中頻繁手動建立和銷燬上下文物件,使得程式碼更加簡潔
下面這些情況中,Flask 會自動啟用應用上下文:
-
使用 flask run 命令啟動程式時
-
使用舊命令
app.run()
啟動程式時 -
執行使用
@app.cli.command()
裝飾器註冊 flask 命令時 -
使用 flask shell 命令啟動 python shell 時
當請求進入時,Flask 會自動啟用請求上下文
手動啟用
在一些特殊情況下需要手動建立或啟用上下文物件
例如在使用 Flask 提供的測試客戶端進行單元測試時,需要手動建立應用上下文和請求上下文,並在測試完成後手動銷燬,以保證測試環境的隔離性
-
手動啟用應用上下文
在 Flask 中,手動啟用應用上下文可以透過使用 app.app_context()
上下文管理器來實現
-
手動啟用請求上下文
總的來說,無論使用哪種方式,啟用 Flask 上下文的目的都是為了能夠在處理請求的過程中訪問請求上下文,並且在請求處理完畢後,正確地銷燬請求上下文
感謝閱讀,喜歡作者就動動小手[一鍵三連],這是我寫作最大的動力