久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Python基礎教程:Flask進擊篇——Flask運行流程

 千鋒Python學堂 2019-10-16

Python基礎教程:Flask進擊篇——Flask運行流程

一次完整的請求

在我們了解Flask運行流程之前,,先看一下我們在瀏覽器一次請求中所經(jīng)歷的過程,下面這張是結合Flask的源碼繪制的一張流程圖

Python基礎教程:Flask進擊篇——Flask運行流程

能看到Flask在一次請求中實際上只是做了最后一部分功能,,這里沒有將Flask的具體處理流程列出來,,我們在下面會繼續(xù)講解。

在上圖中出現(xiàn)WSGIRequestHandler,,WSGI協(xié)議是在Python Web開發(fā)中很核心的部分,,如果想繼續(xù)進擊的話,,需要對這部分有深刻的理解。

這部分我在前面的Python基礎教程有講到過,!

Flask處理流程

我所理解Flask要做的事情,是根據(jù)請求的HTTP協(xié)議中url和method映射相應的處理函數(shù),,處理完并返回。這是基礎的功能,,F(xiàn)lask在這基礎上又增加了一些其他功能,。下面我們就通過Flask的源碼中一些屬性來進行分析,。

Flask部分重要屬性

Python基礎教程:Flask進擊篇——Flask運行流程

Python基礎教程:Flask進擊篇——Flask運行流程

Flask在啟動時已將各屬性根據(jù)需求配置好,但實際映射函數(shù)的屬性就是view_functions,,此屬性類型為字典,,key是endpoint,。

endpoint可自定義,,若不指定將會根據(jù)函數(shù)名生成,,若出現(xiàn)重復的endpoint將會提示錯誤,。

endpoint會與url和method統(tǒng)一封裝成到rule放入到url_map中,,在請求過來時會根據(jù)url和和method生成reuqest到url_map中匹配,,如果匹配到則根據(jù)endpoint獲取到相應的函數(shù)去執(zhí)行,并將結果返回,。這部分可以看Flask源碼部分,。

添加到url_map

# flask/app.py
def add_url_rule(
self,
rule,
endpoint=None,
view_func=None,
provide_automatic_options=None,
**options
):
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)
options["endpoint"] = endpoint
methods = options.pop("methods", None)
if methods is None:
methods = getattr(view_func, "methods", None) or ("GET",)
if isinstance(methods, string_types):
raise TypeError(
"Allowed methods have to be iterables of strings, "
'for example: @app.route(..., methods=["POST"])'
)
methods = set(item.upper() for item in methods)
# Methods that should always be added
required_methods = set(getattr(view_func, "required_methods", ()))
# starting with Flask 0.8 the view_func object can disable and
# force-enable the automatic options handling.
if provide_automatic_options is None:
provide_automatic_options = getattr(
view_func, "provide_automatic_options", None
)
if provide_automatic_options is None:
if "OPTIONS" not in methods:
provide_automatic_options = True
required_methods.add("OPTIONS")
else:
provide_automatic_options = False
# Add the required methods now.
methods |= required_methods
rule = self.url_rule_class(rule, methods=methods, **options)
rule.provide_automatic_options = provide_automatic_options
self.url_map.add(rule)
if view_func is not None:
old_func = self.view_functions.get(endpoint)
if old_func is not None and old_func != view_func:
raise AssertionError(
"View function mapping is overwriting an "
"existing endpoint function: %s" % endpoint
)
self.view_functions[endpoint] = view_func

請求時匹配請求

1.生成請求

	# flask/app.py
def create_url_adapter(self, request):
if request is not None:
subdomain = (
(self.url_map.default_subdomain or None)
if not self.subdomain_matching
else None
)
return self.url_map.bind_to_environ(
request.environ,
server_name=self.config["SERVER_NAME"],
subdomain=subdomain,
)
if self.config["SERVER_NAME"] is not None:
return self.url_map.bind(
self.config["SERVER_NAME"],
script_name=self.config["APPLICATION_ROOT"],
url_scheme=self.config["PREFERRED_URL_SCHEME"],
)
# flask/ctx.py
def match_request(self):
try:
result = self.url_adapter.match(return_rule=True)
self.request.url_rule, self.request.view_args = result
except HTTPException as e:
self.request.routing_exception = e

此處是在生成上下文的push中執(zhí)行會執(zhí)行match_request,這里沒有貼出來,。

實質就是請求過來了,根據(jù)url和method匹配啟動時的url_map,,如果沒有的話則返回匹配不到

2.匹配請求


# flask/app.py
def dispatch_request(self):
req = _request_ctx_stack.top.request
if req.routing_exception is not None:
self.raise_routing_exception(req)
rule = req.url_rule
if (
getattr(rule, "provide_automatic_options", False)
and req.method == "OPTIONS"
):
return self.make_default_options_response()
# otherwise dispatch to the handler for that endpoint
return self.view_functions[rule.endpoint](**req.view_args)

根據(jù)上面從url_map得到的rule,,然后根據(jù)endpoint取得要執(zhí)行的函數(shù),。

Flask另外幾個屬性,則表示在請求之前和請求之后做一些處理,,并且可以針對不同的blueprints來進行處理,,關于blueprints我們等幾個章節(jié)再細分析。

Flask的處理流程

Flask實際的處理流程是什么樣子,,先看一下Flask的源碼

	# flask/app.py
# 1. 先通過wsgi協(xié)議到這個函數(shù)
def __call__(self, environ, start_response):
return self.wsgi_app(environ, start_response)
# 2. 然后調(diào)用這個函數(shù),,處理上下文
def wsgi_app(self, environ, start_response):
# 下文處理?。,?!
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: # noqa: B001
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
if self.should_ignore_error(error):
error = None
ctx.auto_pop(error)
# 3. 請求處理流程
def full_dispatch_request(self):
self.try_trigger_before_first_request_functions()
try:
request_started.send(self)
rv = self.preprocess_request()
if rv is None:
rv = self.dispatch_request()
except Exception as e:
rv = self.handle_user_exception(e)
return self.finalize_request(rv)

基本流程可以看的比較清晰,,至于每個函數(shù)列表的來源以及作用,我在開始的屬性圖上已將其標識出來,。

Python基礎教程:Flask進擊篇——Flask運行流程

至此可以大體知道請求過來之后Flask是如何處理及前期Flask會構建哪些內(nèi)容,。

但Flask還有很多東西。例如我們經(jīng)常使用request,,current_app對象和常用的blueprints是怎么個原理,。

更多的Python基礎教程也會繼續(xù)為大家更新!大家有什么想學的內(nèi)容也可以留言或者私信我,,人多的話,,可以考慮出一期!最近也整理了一些Python基礎教程學習的視頻,,有需要的伙伴可以留言私信我回復Python,,僅30份!

    本站是提供個人知識管理的網(wǎng)絡存儲空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,,請點擊一鍵舉報,。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多