成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

flask route對協(xié)議作用及設計思路解答

89542767 / 410人閱讀

  小編寫這篇文章的一個主要目的,主要是給大家講解一下flask route,講解的內(nèi)容是flask route協(xié)議的一些相關作用,還有具體的一些設計思路,具體的思路性問題,下面去給大家做一個詳細解答。


  引言


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


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


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


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


  flask route設計思路


  源碼版本說明


  本文參考的是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
  }


  這樣做的效果為:


  當http請求的url為'/'時,flask會調(diào)用hello_world函數(shù);


  當http請求的url為'/post/<某整數(shù)值>'(例如/post/32)時,flask會調(diào)用show_post函數(shù);


  flask route的作用


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


  WSGI協(xié)議將處理請求的組件按照功能及調(diào)用關系分成了三種: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位于請求鏈的最后一級,其作用就是生成最終的響應。


  http服務器(比如,nginx)-->WSGI server(比如gunicorn,SimpleHttpServer)-->middleware-->
  middleware-->...-->application


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


  特別重要的:


  在上一小節(jié)的示例中app=Flask(__name__)創(chuàng)建了一個middleware,


  而這個middleware的核心作用是進行請求轉(zhuǎn)發(fā)(request dispatch)。


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


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


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


  進行請求轉(zhuǎn)發(fā)的前提就是能夠建立url與處理函數(shù)之間的映射關系,即route功能。


  因此,在flask中,route是Flask類的一個裝飾器。


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


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


  flask route是url與處理函數(shù)的映射關系;


  在http請求時,F(xiàn)lask這個middleware負責完成對url對應的處理函數(shù)的調(diào)用;


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


  建立一個類Flask,這個類是一個middleware,并且有一個字典型的成員變量url_map;


  url_map={url:function}


  當http請求時,進行request dispatch:根據(jù)url,從url_map中找到function,然后調(diào)用function;


  調(diào)用后續(xù)的middleware或application,并把function的結果傳遞下去。


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


  class Flask(object):
  def __init__(self):
  self.url_map={}#此處定義保存url與處理函數(shù)的映射關系
  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ù)的映射關系建立
  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中找到對應的處理函數(shù),并調(diào)用


  至此,一個簡單的Flaskmiddleware的骨架就完成了。


  上面的Flask類主要功能包括:


  符合WSGI協(xié)議的middleware:可被調(diào)用,并且可以調(diào)用application


  能夠保存url與處理函數(shù)的映射信息


  能夠根據(jù)url找到處理函數(shù)并調(diào)用(即,request dispatch)


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


  werkzeug庫中的Map與Rule在Flask中的應用


  需要指出,上面實現(xiàn)的最簡單的Flask類還是有很多問題的。


  比如,HTTP請求中相同的url,不同的請求方法,比如GET,POST如果對應不同的處理函數(shù),該如何處理?


  flask使用了werkzeug庫中的Map和Rule來管理url與處理函數(shù)映射關系。


  首先需要簡單了解一下Map和Rule的作用:


  在werkzeug中,Rule的主要作用是保存了一組url,endpoint,methods關系:


  每個(url,endpoint,methods)都有一個對應的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對應一個endpoint,一個endpoint對應一個function
  {url:endpoint}#保存url與endpoint之間的關系
  {endpoint:function}#保存endpoint與function之間的關系


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


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


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


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


  如果是通過blueprint建立的映射關系,那么endpoint是blueprint名.處理函數(shù)名;


  因為,每建立一個url-->endpoint-->function關系就會創(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關系的容器Map
  self.view_functions={}#view_functions保存endpoint-->function


  成員變量url_map保存所有的(url,endpoint,method)關系


  成員變量view_functions保存所有的{endpoint,function}關系


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


  route的完整流程


  首先,建立Flask對象:


 app=Flask(__name__)


  然后,建立url與function之間的映射關系:


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


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


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


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


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

  app.run()


  調(diào)用python標準庫提供的WSGI server,在實際使用時,可能是gunicorn或uwsgi。


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


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


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


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


  總結


  flask的Flask類是WSGI的dispatch middleware;
  Flask的url_map保存所有的(url,endpoint,method)映射關系;
  Flask的view_functions保存所有的{endpoint:function}映射關系;
  dispath request就是根據(jù)url找到endpoint,再根據(jù)endpoint找到function,最后調(diào)用function的過程


  綜上所述,這篇文章就給大家介紹到這里了,希望可以給大家?guī)韼椭?/p>

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/128315.html

相關文章

  • flask route設計思路

    摘要:引言本文主要梳理了源碼中的設計思路。協(xié)議將處理請求的組件按照功能及調(diào)用關系分成了三種。不論是什么,最終都會調(diào)用函數(shù)。 引言 本文主要梳理了flask源碼中route的設計思路。首先,從WSGI協(xié)議的角度介紹flask route的作用;其次,詳細講解如何借助werkzeug庫的Map、Rule實現(xiàn)route;最后,梳理了一次完整的http請求中route的完整流程。 flask rou...

    vvpale 評論0 收藏0
  • 怎么使用Flask實現(xiàn)接收與上傳圖片

    小編寫這篇文章的主要目的,主要是來給大家做出一個比較詳細解答,主要是給大家解答關于python中的一些知識,比如Flask實現(xiàn)接手與上傳圖片,下面就給大家詳細解答下?! 〗酉聛斫o搭建講解Flask如何接受圖片文件,上面是復雜寫法,下面是簡單寫法,二選一即可?! ∷悸氛恚航邮請D片->定義一個圖片存放的位置->給圖片重命名(為了唯一性)->保存操作-&...

    89542767 評論0 收藏0
  • 從零開始搭建論壇(一):Web服務器與Web框架

    摘要:服務器通過協(xié)議與客戶端通信,因此也被稱為服務器。本文標題為從零開始搭建論壇一服務器與框架本文鏈接為更多閱讀自己動手開發(fā)網(wǎng)絡服務器一自己動手開發(fā)網(wǎng)絡服務器二自己動手開發(fā)網(wǎng)絡服務器三服務器網(wǎng)關接口實現(xiàn)原理分析最佳實踐指南應用淺談框架編程簡介 之前用 Django 做過一個小的站點,感覺Django太過笨重,于是就準備換一個比較輕量級的 Web 框架來玩玩。Web.py 作者已經(jīng)掛掉,項目好...

    dantezhao 評論0 收藏0
  • [貳]Flask web開發(fā):程序的基本結構

    摘要:本篇對應書本第二章程序的基本結構。初始化導入模塊創(chuàng)建類的實例注對于開發(fā)者來說,傳給應用程序構造函數(shù)的參數(shù)是比較容易弄混淆的。不同的請求方法發(fā)送到相同的上時,會使用不同的視圖函數(shù)進行處理。 本系列筆記是我閱讀Miguel Grinberg的《Flask Web Development》的筆記,標題與書本同步。希望通過記錄技術筆記的方式促進自己對知識的理解。 本篇對應書本第二章:程序的基本...

    maxmin 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<