# 上下文:html
### Local對象:
在`Flask`中,相似於`request`的對象,實際上是綁定到了一個`werkzeug.local.Local`對象上。這樣,即便是同一個對象,那麼在多個線程中都是隔離的。相似的對象還有`session`以及`g`對象。python
### Thread Local對象:
只要知足綁定到這個對象上的屬性,在每一個線程中都是隔離的,那麼他就叫作`Thread Local`對象。flask
### 應用上下文和請求上下文:
應用上下文和請求上下文都是存放到一個`LocalStack`的棧中。和應用app相關的操做就必需要用到應用上下文,好比經過`current_app`獲取當前的這個`app`。和請求相關的操做就必須用到請求上下文,好比使用`url_for`反轉視圖函數。
1. 在視圖函數中,不用擔憂上下文的問題。由於視圖函數要執行,那麼確定是經過訪問url的方式執行的,那麼這種狀況下,Flask底層就已經自動的幫咱們把請求上下文和應用上下文都推入到了相應的棧中。
2. 若是想要在視圖函數外面執行相關的操做,好比獲取當前的app(current_app),或者是反轉url,那麼就必需要手動推入相關的上下文:session
1 * 手動推入app上下文: 2 ```python 3 # 第一種方式: 4 app_context = app.app_context() 5 app_context.push() 6 # 第二種方式: 7 with app.app_context(): 8 print(current_app) 9 ``` 10 * 手動推入請求上下文:推入請求上下文到棧中,會首先判斷有沒有應用上下文,若是沒有那麼就會先推入應用上下文到棧中,而後再推入請求上下文到棧中: 11 ```python 12 with app.test_request_context(): 13 print(url_for('my_list')) 14 ```
### 爲何上下文須要放在棧中:
1. 應用上下文:Flask底層是基於werkzeug,werkzeug是能夠包含多個app的,因此這時候用一個棧來保存。若是你在使用app1,那麼app1應該是要在棧的頂部,若是用完了app1,那麼app1應該從棧中刪除。方便其餘代碼使用下面的app。
2. 若是在寫測試代碼,或者離線腳本的時候,咱們有時候可能須要建立多個請求上下文,這時候就須要存放到一個棧中了。使用哪一個請求上下文的時候,就把對應的請求上下文放到棧的頂部,用完了就要把這個請求上下文從棧中移除掉。app
### 保存全局對象的g對象:
g對象是在整個Flask應用運行期間都是可使用的。而且他也是跟request同樣,是線程隔離的。這個對象是專門用來存儲開發者本身定義的一些數據,方便在整個Flask程序中均可以使用。通常使用就是,將一些常常會用到的數據綁定到上面,之後就直接從g上面取就能夠了,而不須要經過傳參的形式,這樣更加方便。函數
### 經常使用的鉤子函數:
在Flask中鉤子函數是使用特定的裝飾器裝飾的函數。爲何叫作鉤子函數呢,是由於鉤子函數能夠在正常執行的代碼中,插入一段本身想要執行的代碼。那麼這種函數就叫作鉤子函數。(hook)
1. `before_first_request`:Flask項目第一次部署後會執行的鉤子函數。
2. `before_request`:請求已經到達了Flask,可是尚未進入到具體的視圖函數以前調用。通常這個就是在視圖函數以前,咱們能夠把一些後面須要用到的數據先處理好,方便視圖函數使用。
3. `context_processor`:使用這個鉤子函數,必須返回一個字典。這個字典中的值在全部模版中均可以使用。這個鉤子函數的函數是,若是一些在不少模版中都要用到的變量,那麼就可使用這個鉤子函數來返回,而不用在每一個視圖函數中的`render_template`中去寫,這樣可讓代碼更加簡潔和好維護。
4. `errorhandler`:在發生一些異常的時候,好比404錯誤,好比500錯誤。那麼若是想要優雅的處理這些錯誤,就可使用`errorhandler`來出來。須要注意幾點:
* 在errorhandler裝飾的鉤子函數下,記得要返回相應的狀態碼。
* 在errorhandler裝飾的鉤子函數中,必需要寫一個參數,來接收錯誤的信息,若是沒有參數,就會直接報錯。
* 使用`flask.abort`能夠手動的拋出相應的錯誤,好比開發者在發現參數不正確的時候能夠本身手動的拋出一個400錯誤。
示例代碼以下:測試
1 ```python 2 @app.errorhandler(404) 3 def page_not_found(error): 4 return render_template('404.html'),404 5 ```