flask的上下文的机理与应用(转载+整理)
-
請求上下文面向開發(fā)者使用的對象主要是request和session;
-
應(yīng)用上下文面向開發(fā)者使用的對象主要是current_app和g;
#--------------------------------------------------------------------------------------------------------------------------
所謂的上下文,應(yīng)用上,個人理解,其實就是一個作用域的問題.
request獲取的是發(fā)送請求的時候,"發(fā)送請求方"攜帶的信息,具體例子可以參考[13]
session是用來存儲form中提供的一些數(shù)據(jù)的,這些數(shù)據(jù)往往來自用戶的輸入,所以也經(jīng)常有資料說:"避免表單的重復(fù)提交"[14]
?
session 是可以跨 request 使用的,session 的數(shù)據(jù)是經(jīng)過加密后存儲在 cookie 里的,用戶每次 request 都會把這些 cookie 信息發(fā)回來,從而實現(xiàn)跨 request 使用。
g 是面向單個 request 的,一個 request 處理完,g 里的東西就沒了。[15]
可以將g對象看做dict的數(shù)據(jù)結(jié)構(gòu),它支持g.ab方式獲取值和賦值。
current_app其實"沒啥用",而是隱式用到的,代碼如下[16]:
from flask import Flask, current_appapp = Flask(__name__) print(app) #輸出結(jié)果:<Flask '1_current_app'>其余三種的機制如下圖展示[5]:
?
g不能跨請求
session可以跨請求,
request是用來解析請求內(nèi)容的.
然后他們?nèi)叨际窃赪SGI以后,才被我們使用到的.
current_app不會被顯式用到,就不管了.
#---------------------------------------------------------------------------------------------------------
[1]顯示了上下文為什么用棧,但是代碼有些牽強.
[2]沒啥用,[3]提到,g可以當(dāng)做一個dict來使用
?
[4][7][8][9][10][11]都是講鉤子的
[5]的出棧入棧沒講清楚
#----------------------------------------------------------------------------------------------------
舉例:
Flask中new一個對象就是堆,
使用了上下文就是棧,
之所以Flask的上下文需要用到棧,多app存在于單個線程中,
一個線程默認(rèn)情況下只能用同一個棧
?
需要使用上下文+棧的例子
from flask import Flask,current_app from werkzeug.wsgi import DispatcherMiddleware from werkzeug.serving import run_simpleapp1 = Flask("app01") app2 = Flask("app02")@app1.route("/index1") def index1():print(current_app)return "index1"@app2.route("/index2") def index2():print(current_app)return "index2"app = DispatcherMiddleware(app1,{'/sec':app2 }) if __name__ == '__main__':run_simple('localhost',5000,app,)python hello.py
瀏覽器打開:
http://localhost/index1
http://localhost/sec/index2
根據(jù)[17]:
離線測試需要app context 和Request Context分離。
棧用來確保處理的“當(dāng)前的”的app上下文在棧頂
?
#-------------------------------------------附錄---------------------------------------------------------
首先,討論的堆和棧指的是內(nèi)存中的“堆區(qū)”和“棧區(qū)”,OC語言是C語言的超集,所以先了解C語言的內(nèi)存模型的內(nèi)存管理會有很大的幫助。C語言的內(nèi)存模型分為5個區(qū):棧區(qū)、堆區(qū)、靜態(tài)區(qū)、常量區(qū)、代碼區(qū)。每個區(qū)存儲的內(nèi)容如下:
1、棧區(qū):存放函數(shù)的參數(shù)值、局部變量等,由編譯器自動分配和釋放,通常在函數(shù)執(zhí)行完后就釋放了,其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。棧內(nèi)存分配運算內(nèi)置于CPU的指令集,效率很高,但是分配的內(nèi)存量有限,比如iOS中棧區(qū)的大小是2M。
2、堆區(qū):就是通過new、malloc、realloc分配的內(nèi)存塊,編譯器不會負(fù)責(zé)它們的釋放工作,需要用程序區(qū)釋放。分配方式類似于數(shù)據(jù)結(jié)構(gòu)中的鏈表。在iOS開發(fā)中所說的“內(nèi)存泄漏”說的就是堆區(qū)的內(nèi)存。
3、靜態(tài)區(qū):全局變量和靜態(tài)變量(在iOS中就是用static修飾的局部變量或者是全局全局變量)的存儲是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域,未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。程序結(jié)束后,由系統(tǒng)釋放。
4、常量區(qū):常量存儲在這里,不允許修改。
5、代碼區(qū):存放函數(shù)體的二進制代碼。
?
堆和棧的區(qū)別:
1、堆空間的內(nèi)存是動態(tài)分配的,一般存放對象,并且需要手動釋放內(nèi)存。當(dāng)然,iOS引入了ARC(自動引用計數(shù)管理技術(shù))之后,程序員就不需要用代碼管理對象的內(nèi)存了,之前MRC(手動管理內(nèi)存)的時候,程序員需要手動release對象。另外,ARC只是一種中間層的技術(shù),雖然在ARC模式下,程序員不需要像之前那么麻煩管理內(nèi)存,但是需要遵循ARC技術(shù)的規(guī)范操作,比如使用屬性限定符weak、strong、assigen等。因此,如果程序員沒有按ARC的規(guī)則并合理的使用這些屬性限定符的話,同樣是會造成內(nèi)存泄漏的。
2、棧空間的內(nèi)存是由系統(tǒng)自動分配,一般存放局部變量,比如對象的地址等值,不需要程序員對這塊內(nèi)存進行管理,比如,函數(shù)中的局部變量的作用范圍(生命周期)就是在調(diào)完這個函數(shù)之后就結(jié)束了。這些在系統(tǒng)層面都已經(jīng)限定住了,程序員只需要在這種約束下進行程序編程就好,根本就沒有把這塊內(nèi)存的管理權(quán)給到程序員,肯定也就不存在讓程序員管理一說。
?
從申請的大小方面講:
棧空間比較小;
堆空間比較大。
?
從數(shù)據(jù)存儲方面來說:
棧空間中一般存儲基本數(shù)據(jù)類型,對象的地址;
堆空間一般存放對象本身,block的copy等。
?
?
Reference:
[1]flask源碼解析之上下文為什么用棧
[2]Flask快速入門(14) — 請求上下文2
[3]flask基礎(chǔ)之AppContext應(yīng)用上下文和RequestContext請求上下文(六)
[4]應(yīng)用上下文-官方手冊
[5]flask請求和應(yīng)用上下文
[6]flask插件系列之flask_session會話機制
[7]Flask常用的鉤子函數(shù)
[8]Flask框架鉤子函數(shù)使用方式及應(yīng)用場景分析
[9]flask鉤子函數(shù)的作用
[10]Flask系列教程(31)——Flask上下文
[11]flask基礎(chǔ)之請求鉤子(十二)
[12]Flask框架從入門到精通之上下文(二十三)
[13]從零開始學(xué)Python Flask Web(四)--Flask Request請求
[14]HttpSession解決表單的重復(fù)提交
[15]flask 的 g 和session 的區(qū)別怎樣理解
[16]flask之current_app的使用及詳解
[17]深入理解Flask中的上下文
?
?
總結(jié)
以上是生活随笔為你收集整理的flask的上下文的机理与应用(转载+整理)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: xfce开始菜单增加一个新的图标
- 下一篇: 罗盘时钟代码(转载)