標籤:

Flask的g對象,範圍是什麼?

在使用flask中,遇到一個問題很困惑,flask的文檔中

API — Flask Documentation (0.10)

已經是application了 不是request,但是我測試了一下,感覺還是request.代碼如下,請求時,後台會報"_AppCtxGlobals" object has no attribute "count"

錯誤

from flask import Flask,jsonify,g

app = Flask(__name__)

count = []

@app.before_request

def before_request():

print count

@app.route("/")

def hello_world():

count.append(1)

g.count = count

return "Hello World!"

@app.route("/get")

def get():

return jsonify(count=g.count)

if __name__ == "__main__":

app.run(debug=True)


請看下面這段文檔:

flask.g

Just store on this whatever you want. For example a database connection or the user that is currently logged in.

Starting with Flask 0.10 this is stored on the application context and no longer on the request context which means it becomes available if only the application context is bound and not yet a request.

也就是說從0.10開始g兌現就不是在request的級別,而是在應用的級別。鏈接:

API — Flask Documentation (0.10)


這個問題我也遇到了,樓上的各位大牛都說得很抽象,但應該是正確理解這個問題的方向。

我談談自己的理解吧。

1. app context 和 request context

request context 很好理解,看名字就知道是 請求上下文。

而 app context 卻有點誤導性,它的字面意思是 應用上下文,但它不是一直存在的,它只是request context 中的一個對 app 的代理(人),所謂local proxy。它的作用主要是幫助 request 獲取當前的應用,它是伴 request 而生,隨 request 而滅的。

為什麼需要這個代理?因為 flask 支持同時運行多個 app,所以需要為每個 request 綁定到具體的 app context。舉例說 request A 要改變 app A 的屬性,就要把 request A 綁定到 app A 的 context 下。(這裡我是猜的,因為我的水平還不涉及到多應用……)

2. g 和 session

從第一點可以明白 app context 的生命周期其實也只有一個 request 那麼長。

既然這樣,那麼像g這樣的屬於app context 的變數當然也是只有一個 request 那麼長的生命周期了。

這就是為什麼你的代碼在另一個 request 中讀取 g.count 會報錯的原因。

要達到你想要的效果,你可以使用其session。

稍微讀一下源碼你就會發現 session 也是一個 request context 的變數,但它把數據保存到了 cookie 中並發送到了客戶端,客戶端再次請求的時候又帶上了cookie。

以上是我的一些淺見,如果有錯誤希望有人能指出來,感激不盡 : )


Flask本身代碼很簡單,所以,了解Thread local context是最大的難點把。

Local對象的作用就是,它是一個全局對象,你可以往裡面保存東西,a線程保存到local對象的,只有a線程能取到,b線程的只有b線程能取到,如果,a,b保存了名字相同的東西,比如x,a取到的值是自己保存的,不會和b保存的混淆,修改操作也一樣。

request,session,g都是用相同的原理實現的,都是保存在local對象里的線程(包括greenlet協程)安全的變數。

flask自己實現了local對象而不是使用標準庫的threading.Local對象。

仔細讀下werkzueg的local代碼和docstring

fromg對象有什麼用?

==================

好久沒看python了,突然發現這個local對象跟java里的ThreadLocal好像差不多,提供一篇文章參考一下。

徹底理解ThreadLocal


剛剛也在看這個問題,就是Flask的g變數,找到了這篇文章,分享一下

https://blog.tonyseek.com/post/the-context-mechanism-of-flask/

《Flask 0.7中文手冊》P37頁提到,g保存一個request的全局變數(譯者:g保存的是當前請求的全局變數,不同的請求會有不同的全局變數,通過不同的thread id區別)


thread local.


範圍是當前請求內,參考前一位的回答,先去理解什麼是thread local


推薦閱讀:

python有哪些發展方向?
為什麼說浮點數缺乏精確性? python中浮點數運算問題
Apache伺服器上同時運行php的網站和django的網站,該如何配置Apache和Django的URL?
Linux 和 系統安全的前景?
在 Python 中如何判斷輸入數字是實數(整型數字或者浮點型數字)?

TAG:Python | Flask |