flask中請求上下文和應(yīng)用上下文

請求上下文

在flask 0.9版本之前,flask中只有“請求上下文”的概念。那什么是請求上下文呢棵里?

我們先回憶一下在寫flask程序的時候姐呐,經(jīng)常會碰到直接調(diào)用像current_app、request典蝌、session曙砂、g等變量。這些變量看起來似乎是全局變量骏掀,但是實質(zhì)上這些變量并不是真正意義上的全局變量鸠澈。如果將這些變量設(shè)置為全局變量,試想一下截驮,多個線程同時請求程序訪問這些變量時勢必會相互影響笑陈。但是如果不設(shè)置為全局變量,那在編寫代碼時每次都要顯式地傳遞這些變量也是一件非常令人頭疼的事情葵袭,而且還容易出錯涵妥。

為了解決這些問題,flask設(shè)計時采取線程隔離的思路坡锡,也就是說在一次請求的一個線程中可以將其設(shè)置為全局變量蓬网,但是僅限于請求的這個線程內(nèi)部,不同線程通過“線程標(biāo)識符”來區(qū)別鹉勒。這樣就不會影響到其他線程的請求帆锋。flask實現(xiàn)線程隔離主要是使用werkzeug中的兩個類:Local和LocalProxy,這里不再贅述禽额,可以去看看werkzeug的源碼了解一下實現(xiàn)過程锯厢。

實現(xiàn)線程隔離后,為了在一個線程中更加方便使用這些變量绵疲,flask中還有一種堆棧的數(shù)據(jù)結(jié)構(gòu)(通過werkzeug的LocalStack實現(xiàn))哲鸳,可以處理這些變量,但是并不直接處理這些變量盔憨。假如有一個程序得到一個請求徙菠,那么flask會將這個請求的所有相關(guān)信息進(jìn)行打包,打包形成的東西就是處理請求的一個環(huán)境郁岩。flask將這種環(huán)境稱為“請求上下文”(request context)婿奔,之后flask會將這個請求上下文對象放到堆棧中。

這樣问慎,請求發(fā)生時萍摊,我們一般都會指向堆棧中的“請求上下文”對象,這樣可以通過請求上下文獲取相關(guān)對象并直接訪問如叼,例如current_app冰木、request、session、g踊沸。還可以通過調(diào)用對象的方法或者屬性獲取其他信息歇终,例如request.method。等請求結(jié)束后逼龟,請求上下文會被銷毀评凝,堆棧重新等待新的請求上下文對象被放入。

應(yīng)用上下文

應(yīng)用上下文的概念是在flask 0.9中增加的腺律。

既然flask通過線程隔離的方式奕短,將一些變量設(shè)置為線程內(nèi)的“全局”可用。由于請求上下文中包含有當(dāng)前應(yīng)用相關(guān)的信息匀钧,那也就是說可以通過調(diào)用current_app就可以獲取請求所在的正確應(yīng)用而不會導(dǎo)致混淆翎碑。那為什么需要增加一個應(yīng)用上下文的概念呢?

對于單應(yīng)用單請求來說榴捡,使用“請求上下文”確實就可以了杈女。然而,F(xiàn)lask的設(shè)計理念之一就是多應(yīng)用的支持。當(dāng)在一個應(yīng)用的請求上下文環(huán)境中,需要嵌套處理另一個應(yīng)用的相關(guān)操作時(這種情況更多的是用于測試或者在console中對多個應(yīng)用進(jìn)行相關(guān)處理)姆打,“請求上下文”顯然就不能很好地解決問題了根吁,因為魔法current_app無法確定當(dāng)前處理的到底是哪個應(yīng)用。如何讓請求找到“正確”的應(yīng)用呢?我們可能會想到,可以再增加一個請求上下文環(huán)境,并將其推入棧中蝇裤。由于兩個上下文環(huán)境的運行是獨立的,不會相互干擾频鉴,所以通過調(diào)用棧頂對象的app屬性或者調(diào)用current_app(current_app一直指向棧頂?shù)膶ο?也可以獲得當(dāng)前上下文環(huán)境正在處理哪個應(yīng)用栓辜。這種辦法在一定程度上可行,但是如果說對第二個應(yīng)用的處理不涉及到相關(guān)請求垛孔,那也就無從談起“請求上下文”藕甩,更不可能建立請求上下文環(huán)境了。

為了應(yīng)對這個問題周荐,F(xiàn)lask中將應(yīng)用相關(guān)的信息單獨拿出來狭莱,形成一個“應(yīng)用上下文”對象。這個對象可以和“請求上下文”一起使用概作,也可以單獨拿出來使用腋妙。不過有一點需要注意的是:在創(chuàng)建“請求上下文”時一定要創(chuàng)建一個“應(yīng)用上下文”對象。有了“應(yīng)用上下文”對象讯榕,便可以很容易地確定當(dāng)前處理哪個應(yīng)用骤素,這就是魔法`current_app`匙睹。在0.1版本中,current_app是對_request_ctx_stack.top.app的引用谆甜,而在0.9版本中current_app是對_app_ctx_stack.top.app的引用垃僚。其中_request_ctx_stack和_app_ctx_stack分別是存儲請求上下文和應(yīng)用上下文的棧。

這里舉一個多應(yīng)用的例子:

假設(shè)有兩個Flask應(yīng)用:app1和app2规辱。我們假定一種情形:在請求訪問app1時,先要對app2進(jìn)行一些操作栽燕,之后再處理app1內(nèi)的請求罕袋。以下是一些分析過程:

請求訪問app1時,app1會生成一個請求上下文對象碍岔,并且使用with語句產(chǎn)生一個請求上下文環(huán)境浴讯。請求處理的所有過程都會在這個上下文環(huán)境中進(jìn)行。當(dāng)進(jìn)入這個上下文環(huán)境時蔼啦,F(xiàn)lask會將請求上下文對象推入_request_ctx_stack這個棧中榆纽,并且生成一個對應(yīng)的應(yīng)用上下文對象,將其推入_app_ctx_stack棧中捏肢。_app_ctx_stack棧頂指向的是app1奈籽;

當(dāng)在app1的請求上下文環(huán)境中需要對app2進(jìn)行操作時,為了和app1的相關(guān)操作隔離開來鸵赫,可以使用with語句建立一個app2的應(yīng)用上下文環(huán)境衣屏。在這個過程中,會新建一個應(yīng)用上下文對象辩棒,并將其推入_app_ctx_stack棧中狼忱。_app_ctx_stack棧頂指向的是app2;

當(dāng)退出app2的應(yīng)用上下文環(huán)境一睁,重新進(jìn)入app1的請求上下文環(huán)境時钻弄,_app_ctx_stack棧會銷毀app2的應(yīng)用上下文對象,它的棧頂指向的是app1者吁。

通過以上一個假象的例子窘俺,我們始終可以使用current_app來表示當(dāng)前處理的Flask應(yīng)用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末砚偶,一起剝皮案震驚了整個濱河市批销,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌染坯,老刑警劉巖均芽,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異单鹿,居然都是意外死亡掀宋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來劲妙,“玉大人湃鹊,你說我怎么就攤上這事×头埽” “怎么了币呵?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長侨颈。 經(jīng)常有香客問我余赢,道長,這世上最難降的妖魔是什么哈垢? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任妻柒,我火速辦了婚禮,結(jié)果婚禮上耘分,老公的妹妹穿的比我還像新娘举塔。我一直安慰自己,他們只是感情好求泰,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布央渣。 她就那樣靜靜地躺著,像睡著了一般拜秧。 火紅的嫁衣襯著肌膚如雪痹屹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天枉氮,我揣著相機(jī)與錄音志衍,去河邊找鬼。 笑死聊替,一個胖子當(dāng)著我的面吹牛楼肪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惹悄,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼春叫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泣港?” 一聲冷哼從身側(cè)響起暂殖,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎当纱,沒想到半個月后呛每,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡坡氯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年晨横,在試婚紗的時候發(fā)現(xiàn)自己被綠了洋腮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡手形,死狀恐怖啥供,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情库糠,我是刑警寧澤伙狐,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站曼玩,受9級特大地震影響鳞骤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜黍判,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望篙梢。 院中可真熱鬧顷帖,春花似錦、人聲如沸渤滞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妄呕。三九已至陶舞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绪励,已是汗流浹背肿孵。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留疏魏,地道東北人停做。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像大莫,于是被迫代替她去往敵國和親蛉腌。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容