最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

flask?route對協(xié)議作用及設(shè)計思路

 更新時間:2022年07月05日 16:16:03   作者:_Zhao  
這篇文章主要為大家介紹了flask?route對協(xié)議作用及設(shè)計思路詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

本文主要梳理了flask源碼中route的設(shè)計思路。

首先,從WSGI協(xié)議的角度介紹flask route的作用;

其次,詳細講解如何借助werkzeug庫的Map、Rule實現(xiàn)route;

最后,梳理了一次完整的http請求中route的完整流程。

flask route 設(shè)計思路

源碼版本說明

本文參考的是flask 0.5版本的代碼。

flask 0.1版本的代碼非常短,只有600多行,但是這個版本缺少blueprint機制。

因此,我參考的是0.5版本。

flask route示例

直接使用flask官方文檔中的例子

from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
    return 'Hello World!'
@app.route('/post/')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return 'Post %d' % post_id
if __name__ == '__main__':
    app.run()

此例中,使用app.route裝飾器,完成了以下兩個url與處理函數(shù)的route:

{ 
    '/': hello_world, 
    '/post/' : show_post
}

這樣做的效果為:
當(dāng)http請求的url為'/'時,flask會調(diào)用hello_world函數(shù);
當(dāng)http請求的url為'/post/<某整數(shù)值>'(例如/post/32)時,flask會調(diào)用show_post函數(shù);

flask route的作用

從上面的示例中其實可以明白:flask route的作用就是建立url與處理函數(shù)的映射。

WSGI協(xié)議將處理請求的組件按照功能及調(diào)用關(guān)系分成了三種:server, middleware, application。

其中,server可以調(diào)用middleware和application,middleware可以調(diào)用application。

符合WSGI的框架對于一次http請求的完整處理過程為:

server讀取解析請求,生成environ和start_response,然后調(diào)用middleware;

middleware完成自己的處理部分后,可以繼續(xù)調(diào)用下一個middleware或application,形成一個完整的請求鏈;

application位于請求鏈的最后一級,其作用就是生成最終的響應(yīng)。

 http服務(wù)器(比如,nginx)--&gt; WSGI server(比如gunicorn,SimpleHttpServer)--&gt;middleware--&gt;
 middleware--&gt; ... --&gt;application

如果接觸過Java Web 開發(fā)的人可能會立刻發(fā)現(xiàn),這與servlet中的middleware機制是完全一致的。

特別重要的:

在上一小節(jié)的示例中app = Flask(__name__)創(chuàng)建了一個middleware,
而這個middleware的核心作用是進行請求轉(zhuǎn)發(fā)(request dispatch)。

上面這句話非常重要,請在心里重復(fù)一百遍。
上面這句話非常重要,請在心里重復(fù)一百遍。
上面這句話非常重要,請在心里重復(fù)一百遍。

進行請求轉(zhuǎn)發(fā)的前提就是能夠建立url與處理函數(shù)之間的映射關(guān)系,即route功能。
因此,在flask中,route是Flask類的一個裝飾器。

flask route的實現(xiàn)思路

通過上一小節(jié),我們知道以下兩點:

  • flask route 是url與處理函數(shù)的映射關(guān)系;
  • 在http請求時,Flask這個middleware負責(zé)完成對url對應(yīng)的處理函數(shù)的調(diào)用;

那么,如果是我們自己來實現(xiàn)route,思路也很簡單:

  • 建立一個類Flask,這個類是一個middleware,并且有一個字典型的成員變量url_map
  • url_map = {url : function}
  • 當(dāng)http請求時,進行request dispatch:根據(jù)url,從url_map中找到function,然后調(diào)用function;
  • 調(diào)用后續(xù)的middleware或application,并把function的結(jié)果傳遞下去。

flask的實現(xiàn)思路也是這樣的。

class Flask(object):
    def __init__(self):
        self.url_map = {}  # 此處定義保存url與處理函數(shù)的映射關(guān)系
    def __call__(self, environ, start_response):  # 根據(jù)WSGI協(xié)議,middleware必須是可調(diào)用對象
        self.dispatch_request()    # Flask的核心功能 request dispatch
        return application(environ, start_response)  #最后調(diào)用下一級的application
    def route(self, rule):  # Flask使用裝飾器來完成url與處理函數(shù)的映射關(guān)系建立
        def decorator(f):   # 簡單,侵入小,優(yōu)雅
            self.url_map[rule] = f
            return f
        return decorator
    def dispath_request(self):
        url = get_url_from_environ() #解析environ獲得url 
        return self.url_map[url]() #從url_map中找到對應(yīng)的處理函數(shù),并調(diào)用

至此, 一個簡單的Flaskmiddleware的骨架就完成了。
上面的Flask類主要功能包括:

  • 符合WSGI協(xié)議的middleware:可被調(diào)用,并且可以調(diào)用application
  • 能夠保存url與處理函數(shù)的映射信息
  • 能夠根據(jù)url找到處理函數(shù)并調(diào)用(即,request dispatch)

當(dāng)然,在實際中,不可能這么簡單,但是基本思路是一致的。

werkzeug庫中的Map與Rule在Flask中的應(yīng)用

需要指出,上面實現(xiàn)的最簡單的Flask類還是有很多問題的。
比如,HTTP請求中相同的url,不同的請求方法,比如GET,POST如果對應(yīng)不同的處理函數(shù),該如何處理?

flask使用了werkzeug庫中的MapRule來管理url與處理函數(shù)映射關(guān)系。

首先需要簡單了解一下MapRule的作用:

werkzeug中,Rule的主要作用是保存了一組url,endpointmethods關(guān)系:

每個(url, endpoint, methods)都有一個對應(yīng)的Rule對象:

其實現(xiàn)如下:

class Rule(object):
    def __init__(self, url, endpoint, methods):
        self.rule = url
        self.endpoint = endpoint
        self.methods = methods

這里需要解釋一下endpoint

前面說過:url與其處理函數(shù)可以使用一個字典來實現(xiàn):{url: function}

flask在實現(xiàn)的時候,在中間加了一個中介endpoint,于是,url與處理函數(shù)的映射變成了這樣:

url-->endpoint-->function #一個url對應(yīng)一個endpoint,一個endpoint對應(yīng)一個function
{url: endpoint} # 保存url與endpoint之間的關(guān)系
{endpoint: function} #保存endpoint與function之間的關(guān)系

于是,剛才我們實現(xiàn)的簡單的flask骨架中{url: function}的字典,就變成了{endpoint: function},而{url: endpoint}這個映射關(guān)系就需要借助MapRule這兩個類來完成。

可以發(fā)現(xiàn):endpoint就是url和處理函數(shù)映射關(guān)系中的一個中介,所以,它可以是任何可以用作字典鍵的值,比如字符串。

但是在實際使用中endpoint,一般endpoint均為字符串,并且默認(rèn)情況下:

  • 如果是通過Flask.route裝飾器建立的映射關(guān)系,那么endpoint就是處理函數(shù)的函數(shù)名;
  • 如果是通過blueprint建立的映射關(guān)系,那么endpoint是blueprint名.處理函數(shù)名;

因為,每建立一個url-->endpoint-->function關(guān)系就會創(chuàng)建一個Rule對象,所以,會有很多Rule對象存在。
 

Map的作用則是保存所有Rule對象。

所以,一般情況下Map的用法如下:

    m = Map([
            Rule('/', endpoint='index'),
            Rule('/downloads/', endpoint='downloads/index'),
            Rule('/downloads/', endpoint='downloads/show')
           ])

在flask的源碼中

class Flask(object):
    def __init__(self):
        self.url_map = Map()  # url_map為保存所有Rule關(guān)系的容器Map
        self.view_functions = {} # view_functions保存endpoint--&gt;function
  • 成員變量url_map保存所有的(url, endpoint, method)關(guān)系
  • 成員變量view_functions保存所有的{endpoint, function}關(guān)系

所以,對于一個url,只要能找到(url,endpoint,method),就能根據(jù)endpoint找到對應(yīng)的function。

route的完整流程

首先,建立Flask對象:

app = Flask(__name__)

然后,建立urlfunction之間的映射關(guān)系:

@app.route('/')
def hello_world():
    return 'Hello World!'

在裝飾器route中,創(chuàng)建(url, endpoint, method){endpoint: function}兩組映射關(guān)系:

if endpoint is None:
    endpoint = view_func.__name__ # 默認(rèn)使用響應(yīng)函數(shù)名作為endpoint
self.url_map.add(Rule(url, endpoint, method)) # 保存(url, endpoint, method)映射關(guān)系
self.view_functions[endpoint] = view_func  # 保存{endpoint: function}映射關(guān)系

這樣,就完成了對url和響應(yīng)函數(shù)的映射關(guān)系。

下一步,調(diào)用WSGI server響應(yīng)http請求,在文章開始的示例中使用:

app.run()

調(diào)用python標(biāo)準(zhǔn)庫提供的WSGI server,在實際使用時,可能是gunicornuwsgi。

不論server是什么,最終都會調(diào)用Flask.__call__函數(shù)。這個函數(shù)完成request dispatch的任務(wù)。

對于request dispatch而言,首先根據(jù)請求,解析environ,得到url,然后調(diào)用Map.match函數(shù),這個函數(shù)會最終找到預(yù)先保存的(url, endpoint, method)映射,然后返回(endpoint, url請求參數(shù)),由于得到了endpoint,然后,可以從Flask.view_functions中直接取到對應(yīng)的響應(yīng)函數(shù),所以,可以直接進行函數(shù)調(diào)用

self.view_functions[endpoint](url請求參數(shù))

至此,就完成了完整的route。

總結(jié)

flaskFlask類是WSGIdispatch middleware;

Flaskurl_map保存所有的(url, endpoint, method)映射關(guān)系;

Flaskview_functions保存所有的{endpoint: function}映射關(guān)系;

dispath request就是根據(jù)url找到endpoint,再根據(jù)endpoint找到function,最后調(diào)用function的過程

以上就是flask route對協(xié)議作用及設(shè)計思路的詳細內(nèi)容,更多關(guān)于flask route協(xié)議設(shè)計的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • python判斷字符串或者集合是否為空的實例

    python判斷字符串或者集合是否為空的實例

    今天小編就為大家分享一篇python判斷字符串或者集合是否為空的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • python 限制函數(shù)執(zhí)行時間,自己實現(xiàn)timeout的實例

    python 限制函數(shù)執(zhí)行時間,自己實現(xiàn)timeout的實例

    今天小編就為大家分享一篇python 限制函數(shù)執(zhí)行時間,自己實現(xiàn)timeout的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • Python中層次聚類的詳細講解

    Python中層次聚類的詳細講解

    層次聚類( Hierarchical Clustering )是聚類算法的一種,通過計算不同類別的相似度類創(chuàng)建一個有層次的嵌套的樹,下面這篇文章主要給大家介紹了關(guān)于Python中層次聚類的詳細講解,需要的朋友可以參考下
    2022-12-12
  • Python網(wǎng)絡(luò)請求使用Requests庫抓取解析數(shù)據(jù)

    Python網(wǎng)絡(luò)請求使用Requests庫抓取解析數(shù)據(jù)

    在網(wǎng)絡(luò)編程中,請求和接收數(shù)據(jù)是最常見的任務(wù)之一,Python的Requests庫提供了豐富的功能,使得HTTP請求變得非常簡單,在本文中,我們將了解如何使用Requests庫發(fā)起HTTP請求,并解析返回的數(shù)據(jù)
    2023-08-08
  • Python+OpenCV實現(xiàn)分水嶺分割算法的示例代碼

    Python+OpenCV實現(xiàn)分水嶺分割算法的示例代碼

    分水嶺算法是用于分割的經(jīng)典算法,在提取圖像中粘連或重疊的對象時特別有用。本文將用Python+OpenCV實現(xiàn)這一算法,需要的可以參考一下
    2022-08-08
  • 一行Python3代碼實現(xiàn)解析地址信息

    一行Python3代碼實現(xiàn)解析地址信息

    在日常數(shù)據(jù)處理的過程中,有時候拿到手的是完整的地址信息,如果需要從地址信息中解析出相應(yīng)的各級行政單元名稱,方式有很多,而今天要介紹的方式只需要一行代碼即可快速實現(xiàn),快跟隨小編一起學(xué)習(xí)一下吧
    2022-05-05
  • Python使用matplotlib時顯示中文亂碼解決方法(或更改字體)

    Python使用matplotlib時顯示中文亂碼解決方法(或更改字體)

    這篇文章主要給大家介紹了關(guān)于Python使用matplotlib時顯示中文亂碼的解決方法(或更改字體),在Matplotlib中,中文亂碼問題通常出現(xiàn)在圖表的標(biāo)題、標(biāo)簽和刻度上,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-12-12
  • Python中使用zip函數(shù)的七重境界解析

    Python中使用zip函數(shù)的七重境界解析

    這篇文章主要介紹了Python中使用zip函數(shù)的七重境界,重點介紹了Python中功能強大的zip 函數(shù)的多種用法,并給出了相應(yīng)的代碼示例,需要的朋友可以參考下
    2022-12-12
  • 解決Atom安裝Hydrogen無法運行python3的問題

    解決Atom安裝Hydrogen無法運行python3的問題

    今天小編就為大家分享一篇解決Atom安裝Hydrogen無法運行python3的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-08-08
  • Python讀取網(wǎng)頁內(nèi)容的方法

    Python讀取網(wǎng)頁內(nèi)容的方法

    這篇文章主要介紹了Python讀取網(wǎng)頁內(nèi)容的方法,實例分析了Python基于URL讀取網(wǎng)頁內(nèi)容的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07

最新評論

富裕县| 叶城县| 江安县| 兰州市| 津市市| 田阳县| 锡林浩特市| 射阳县| 韩城市| 河东区| 新兴县| 富蕴县| 开江县| 平邑县| 丹寨县| 都安| 洪洞县| 涟源市| 扬中市| 达拉特旗| 青阳县| 佛坪县| 南川市| 凤城市| 和平区| 嘉鱼县| 贵港市| 衡山县| 罗源县| 闽清县| 长沙市| 天气| 静安区| 兴文县| 黎川县| 正蓝旗| 昌邑市| 南涧| 和政县| 大同县| 武冈市|