91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2020-08-13 18:13:56 來源:ITPUB博客 閱讀:221 作者:千鋒Python唐小強 欄目:編程語言

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

一次完整的請求

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

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

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

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

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

Flask處理流程

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

Flask部分重要屬性

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

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

endpoint可自定義,若不指定將會根據函數名生成,若出現重復的endpoint將會提示錯誤。

endpoint會與url和method統一封裝成到rule放入到url_map中,在請求過來時會根據url和和method生成reuqest到url_map中匹配,如果匹配到則根據endpoint獲取到相應的函數去執行,并將結果返回。這部分可以看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中執行會執行match_request,這里沒有貼出來。

實質就是請求過來了,根據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)

根據上面從url_map得到的rule,然后根據endpoint取得要執行的函數。

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

Flask的處理流程

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

	# flask/app.py
	# 1. 先通過wsgi協議到這個函數
 def __call__(self, environ, start_response):
 return self.wsgi_app(environ, start_response)
	# 2. 然后調用這個函數,處理上下文
 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)

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

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

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

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

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

麟游县| 霞浦县| 军事| 涞水县| 原平市| 张家港市| 阜新市| 侯马市| 江油市| 峡江县| 台中县| 湖南省| 镇雄县| 潍坊市| 德兴市| 桑日县| 昭苏县| 五寨县| 大余县| 鄂州市| 德格县| 陇南市| 图木舒克市| 秦皇岛市| 永顺县| 中宁县| 察隅县| 自治县| 友谊县| 靖州| 名山县| 长海县| 日喀则市| 万盛区| 辽宁省| 班玛县| 平和县| 庆城县| 南京市| 丘北县| 广丰县|