當前位置:
首頁 > 最新 > Werkzeug庫:routing模塊

Werkzeug庫:routing模塊

來源: Learn Python

fanchunke.me/Flask/Werkzeug庫——routing模塊/

Werkzeug庫的routing模塊的主要功能在於URL解析。對於WSGI應用來講,不同的URL對應不同的視圖函數,routing模塊則會對請求信息的URL進行解析並匹配,觸發URL對應的視圖函數,以此生成一個響應信息。routing模塊的解析和匹配功能主要體現在三個類上:Rule、Map和MapAdapter。

Rule類

Rule類繼承自RuleFactory類。一個Rule的實例代表一個URL模式,一個WSGI應用可以處理很多不同的URL模式,這也就是說可以產生很多不同的Rule實例。這些Rule實例最終會作為參數傳遞給Map類,形成一個包含所有URL模式的對象,通過這個對象可以解析並匹配請求對應的視圖函數。

關於Rule類有一些常用的方法:

empty() ——在實際情況中,Rule實例會和一個Map實例進行綁定。通過empty()方法可以將Rule實例和Map實例解除綁定。

get_empty_kwargs() ——在empty()方法中調用,可以獲得之前Rule實例的參數,以便重新構造一個Rule實例。

get_rules(map) ——這個方法是對RuleFactory類中get_rules方法的重寫,返回Rule實例本身。

refresh() ——當修改Rule實例(URL規則)後可以調用該方法,以便更新Rule實例和Map實例的綁定關係。

bind(map, rebind=False) ——將Rule實例和一個Map實例進行綁定,這個方法會調用complie()方法,會給Rule實例生成一個正則表達式。

complie() ——根據Rule實例的URL模式,生成一個正則表達式,以便後續對請求的path進行匹配。

match(path) ——將Rule實例和給定的path進行匹配。在調用complie()方法生成的正則表達式將會對path進行匹配。如果匹配,將返回這個path中的參數,以便後續過程使用。如果不匹配,將會由其他的Rule實例和這個path進行匹配。

注意: 在對給定的URL進行匹配的過程中,會使用一些Converters。關於Converters的信息後續加以介紹。

Map類

通過Map類構造的實例可以存儲所有的URL規則,這些規則是Rule類的實例。Map實例可以 通過後續的調用和給定的URL進行匹配。

關於Map類有一些常用的方法:

add(rulefactory) ——這個方法在構造Map實例的時候就會調用,它會將所有傳入Map類中的Rule實例和該Map實例建立綁定關係。該方法還會調用Rule實例的bind方法。

bind方法 ——這個方法會生成一個MapAdapter實例,傳入MapAdapter的包括一些請求信息,這樣可以調用MapAdapter實例的方法匹配給定URL。

bind_to_environ方法 ——通過解析請求中的environ信息,然後調用上面的bind方法,最終會生成一個MapAdapter實例。

MapAdapter類

MapAdapter類執行URL匹配的具體工作。關於MapAdapter類有一些常用的方法:

dispatch方法 ——該方法首先會調用MapAdapter實例的match()方法,如果有匹配的Rule,則會執行該Rule對應的視圖函數。

match方法 ——該方法將會進行具體的URL匹配工作。它會將請求中的url和MapAdapter實例中的所有Rule進行匹配,如果有匹配成功的,則返回該Rule對應的endpoint和一些參數rv。endpoint一般會對應一個視圖函數,返回的rv可以作為參數傳入視圖函數中。

一個簡單的例子

為了說明routing模塊的工作原理,這裡使用Werkzeug文檔中的一個例子,稍加改動後如下所示:

fromwerkzeug.routingimportMap,Rule,NotFound,RequestRedirect,HTTPException

url_map=Map([

Rule( / ,endpoint= blog/index ),

Rule( // ,endpoint= blog/archive ),

Rule( /// ,endpoint= blog/archive ),

Rule( //// ,endpoint= blog/archive ),

Rule( //// ,

endpoint= blog/show_post ),

Rule( /about ,endpoint= blog/about_me ),

Rule( /feeds/ ,endpoint= blog/feeds ),

Rule( /feeds/.rss ,endpoint= blog/show_feed )

])

defapplication(environ,start_response):

urls=url_map.bind_to_environ(environ)

try:

endpoint,args=urls.match()

exceptHTTPException,e:

returne(environ,start_response)

start_response( 200 OK ,[( Content-Type , text/plain )])

return[ Rule points to %r with arguments %r %(endpoint,args)]

if__name__== __main__ :

fromwerkzeug.servingimportrun_simple

run_simple( localhost ,4000,application)

這裡我們使用werkzeug自帶的伺服器模塊構造了一個Web伺服器,並且設計了一個簡單的WSGI應用——application。這個Web伺服器可以根據URL的不同返回不同的結果。關於伺服器的構造這裡不再贅述,以下部分簡單對URL Routing過程進行分析:

1. 設計URL模式

設計URL模式的過程就是構造Rule實例的過程。上面的例子中我們構造了8個Rule實例,分別對應8個不同的URL模式。每個Rule實例還對應一個endpoint,這個endpoint可以和視圖函數進行對應,以便訪問某個URL時,可以觸發與之對應的視圖函數。下面的例子展示了endpoint和視圖函數的對應關係。

fromwerkzeug.wrappersimportResponse

fromwerkzeug.routingimportMap,Rule

defon_index(request):

returnResponse( Hello from the index )

url_map=Map([Rule( / ,endpoint= index )])

views={ index :on_index}

2. 構造Map實例

構造Map實例時,會調用它的add(rulefactory)方法。這個方法會在Map實例和各個Rule實例之間建立綁定關係,並通過調用Rule實例的bind()方法為每個Rule實例生成一個正則表達式。

例如,對於 /about 這個URL,它對應的正則表達式為:

^\\/about$

對於 //// 這個URL,它對應的正則表達式為:

^\\/(?P\d+)\/(?P\d+)\/(?P\d+)(?/?)$

3. 構造MapAdapter實例

在設計WSGI應用時,上述例子通過url_map.bind_to_environ(environ)構建了一個MapAdapter實例。這個實例將請求的相關信息和已經創建好的Map實例放在一起,以便進行URL匹配。

進行URL匹配的過程是通過調用MapAdapter實例的match()方法進行的。實質上,這個方法會將請求中的path傳入到所有Rule實例的match(path)方法中,經過正則表達式的匹配來分析path是否和某個Rule實例匹配。如果匹配則返回對應的endpoint和其他的參數,這可以作為參數傳入視圖函數。

4. 訪問URL可得相關結果

之後,訪問URL可以得到相對應的結果。

例如,訪問http://localhost:4000/2017/,可以得到:

Rule points to blog/archive with arguments { year : 2017}

訪問http://localhost:4000/2017/3/20/,可以得到:

Rule points to blog/archive with arguments { month : 3, day : 20, year : 2017}

訪問http://localhost:4000/about,可以得到:

Rule points to blog/about_me with arguments {}

看完本文有收穫?請轉發分享給更多人

關注「Python開發者」,提升Python技能

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python開發者 的精彩文章:

Python 增強的生成器:協程
Python這麼熱,要不要追趕 Python 的熱潮?
Python :淺析 return 和 finally 共同挖的坑
頂會審稿人領你打開深度學習的大門
Python 線性分類模型簡介

TAG:Python開發者 |