flask 核心 之 應用上下文 及 請求上下文

2021-09-13 08:21:34 字數 3442 閱讀 4149

werkzeugs 是 flask 的底層wsgi庫。

def dispath_request(self, request):

return response('hello world!')

request = request(environ)

response = self.dispath_request(request)

return response(environ, start_response)

environ:包含全部的http請求資訊的字典,由wsgi server解包 http 請求生成。

start_response:乙個wsgi server提供的函式,呼叫可以返回相應的狀態嗎和http報文頭,函式在返回前必須呼叫一次。

flask有兩種context(上下文),分別是

在 'flask/globals.py' **中:

# context locals

_request_ctx_stack = localstack()

# localstack 是由werkzeug提供的棧結構類提供了push、pop等方法

# 並且local物件是werkzeug開發的類似 thinking.local(用於隔離不同執行緒間的全域性變數) 物件,實現了在同乙個協程中資料的隔離和全域性性,具體怎麼實現看源**,暫時沒看明白

# partial(_lookup_req_object, 'request') 總是返回 localstack 棧頂物件的 request 屬性

# localproxy 用於**local物件和localstack物件,至於為什麼使用**。。

request = localproxy(partial(_lookup_req_object, 'request'))

session = localproxy(partial(_lookup_req_object, 'session'))

flask local

為什麼要使用 localproxy 而不直接使用 local 和 localstack #

### 在 `flask/ctx.py` **中

# # but there a basic "refcount" is enough to track them.

self._refcnt = 0

self._refcnt += 1

if hasattr(sys, 'exc_clear'):

sys.exc_clear()

## 在 flask/cli.py 中有

# @click.pass_context

def decorator(__ctx, *args, **kwargs): # decorator 被裝飾器後 _ctx 引數是 threading 的 local() 物件

return __ctx.invoke(f, *args, **kwargs)

# requestcontext 請求上下文##

def request_context(self, environ): # 一次請求的環境變數

return requestcontext(self, environ)

## 在flask/ctx.py下:

#class requestcontext(object):

if request is none:

self.request = request

self.flashes = none

self.session = none

......

def push(self):

..._request_ctx_stack.push(self) ##

ctx = self.request_context(environ)

error = none

try:

try:

ctx.push()

response = self.full_dispatch_request()

except exception as e:

error = e

response = self.handle_exception(e)

except:

error = sys.exc_info()[1]

raise

return response(environ, start_response)

finally:

if self.should_ignore_error(error):

error = none

ctx.auto_pop(error)

原始碼中有這麼幾個裝飾器:

# url_defaults(self, f) 和 url_value_preprocessor(self, f) 的使用

from flask import blueprint, render_template

profile = blueprint('profile', __name__, url_prefix='/')

@profile.url_defaults

def add_user_url_slug(endpoint, values):

values.setdefault('user_url_slug', g.user_url_slug)

@profile.url_value_preprocessor

def pull_user_url_slug(endpoint, values):

g.user_url_slug = values.pop('user_url_slug')

query = user.query.filter_by(url_slug=g.user_url_slug)

g.profile_owner = query.first_or_404()

@profile.route('/')

def timeline():

return render_template('profile/timeline.html')

@profile.route('/photos')

def photos():

return render_template('profile/photos.html')

@profile.route('/about')

def about():

return render_template('profile/about.html')

方法:click 包 把python**打包成命令列工具

mimetypes 包 檢視檔案型別

itsdangerous 簽名 序列化字串

Flask之請求上下文 應用上下文的概述

flask中有兩種上下文,請求上下文和應用上下文 一 請求上下文 request context request和session都屬於請求上下文物件。2.g 處理請求時,用於臨時儲存的物件,每次請求都會重設這個變數。比如 我們可以獲取一些臨時請求的使用者資訊。request 在每次http請求發生時...

Flask 中請求上下文和應用上下文的區別和作用?

兩者作用 請求上下文 request context flask從客戶端收到請求時,要讓檢視函式能訪問一些物件,這樣才能處理請求。請求物件是一 個很好的例子,它封裝了客戶端傳送的http 請求。要想讓檢視函式能夠訪問請求物件,乙個顯而易見的方式是將其作為引數傳入檢視函式,不過 這會導致程式中的每個檢...

二十 用上下文管理應用

使用react可以很容易通過react元件跟蹤資料流。當你看到乙個元件,你就可以看到哪些props正在傳遞,這使得你的應用很容易知道在做什麼。在某些情況下,你希望通過元件樹傳遞資料,而不是在每個級別的中元件手動傳遞props,你可以直接在react中使用強大的 context 來做到這一點。絕大多數...