20、Flask实战第20天:Flask上下文
Local線程隔離對象
我們知道通過request可以獲取表單中的數據。如果是多個用戶同時在用網站,而全局request就只有一個,那么Flask是如何分辨哪用戶對應哪個請求呢?
這種情況下,就會用到Local對象,只要綁定在Local對象上的屬性,在每個線程中都是隔離的
?我們看看,使用多線程修改值,不用local對象時,因為request是全局共享的,只要修改了它的值,就會影響到其它線程!
當我們使用Local對象綁定時,因為在每個線程中都是隔離的,所以不會影響到其它線程
?
總結:
1、在Flask中,類似于request的對象(還有session等),其實是綁定到了一個werkzeug.local.Local對象上。這樣,即使是同一個對象,那么多個線程中都是隔離的。
2、只要滿足綁定到這個對象上的屬性,在每個線程中都是隔離的,那么它就叫做Thread Local對象
?
app上下文
app上下文存放在一個LocalStack的棧中,和app應用相關的操作就必須要應用上下文,比如通過current_app獲取當前這個app的名字
啟動訪問瀏覽器首頁
如果我們把print(current_app.name)放到視圖函數外面,就會報錯
在視圖函數中,不用擔心上下文的問題,因為視圖函數要執行,肯定是通過url的方式執行的,這種情況下,Flask底層就已經自動的幫我們把應用上下文推入到相應的棧中。如果要在視圖函數外面執行相關的操作,就必須手動推入上下文。
?
請求上下文
請求上下文也是存放在一個LocalStack棧中,請求的相關的操作就必須用到請求的上下文,比如url_for反轉視圖函數
?因為在視圖函數圖,會自動推入上下文,所以正常執行
當在視圖函數外面執行,沒有請求上下文的關系則會報錯
錯誤提示是沒有app上下文推入,那么我們就使用前面的方法推入app上下文
推入app上下文后,又出錯,沒有請求上下文
因此,手動推入請求上下文:推入請求上下文到棧中,會首先判斷有沒有應用上下文,如果沒有那么就會先推入應用上下文到棧中,然后再推入請求上下文到棧中
?
為什么上下文需要放在棧中
2、Flask底層是基于werkzeug,werkzeug是可以包含多個app的,所以這時候用一個棧來保存,如果你在使用app1,那么app1應該是要在棧的頂部,如果用完了app1那么app應該從棧中刪除,方便其他代碼使用下面的app。
2、如果在寫測試代碼,或者離線腳本的時候,我們有時候可能需要創建多個請求上下文,這時候就需要存放到一個棧中了。使用哪個請求上下文的時候,就把對應的請求上下文放到棧的頂部,用完了就要把這個請求上下文從棧中移除掉。
?
線程隔離的g對象
g對象是在整個Flask應用運行期間都是可以使用的,并且它也是跟request一樣是線程隔離的。這個對象是專門用來存儲開發者自定義的一些數據,方便在整個Flask程序中都可以使用。一般使用就是,將一些經常會用到的數據綁定到上面,以后就直接從g上面取就可以了,而不是通過傳參的形式,這樣更加方便。
?
比如當我們訪問首頁的時候會調用一些函數打印日志,并且這個這個會打印出用戶名
新建一個utils.py專門用來存儲這些工具函數,如下
這樣做雖然可以實現需求,但是每條調用都必須傳入username參數才可以,如果使用g就方便多了
把username存入到g.username中
函數那邊直接調用g.username就可以了
轉載于:https://www.cnblogs.com/sellsa/p/9378065.html
總結
以上是生活随笔為你收集整理的20、Flask实战第20天:Flask上下文的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GoldenGate安装配置
- 下一篇: 云服务器配置出现的问题 2