国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

flask route對(duì)協(xié)議作用及設(shè)計(jì)思路解答

89542767 / 407人閱讀

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


  引言


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


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


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


  最后,梳理了一次完整的http請(qǐng)求中route的完整流程。


  flask route設(shè)計(jì)思路


  源碼版本說(shuō)明


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


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


  因此,我參考的是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裝飾器,完成了以下兩個(gè)url與處理函數(shù)的route:


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


  這樣做的效果為:


  當(dāng)http請(qǐng)求的url為'/'時(shí),flask會(huì)調(diào)用hello_world函數(shù);


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


  flask route的作用


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


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


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


  符合WSGI的框架對(duì)于一次http請(qǐng)求的完整處理過(guò)程為:


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


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


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


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


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


  特別重要的:


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


  而這個(gè)middleware的核心作用是進(jìn)行請(qǐng)求轉(zhuǎn)發(fā)(request dispatch)。


  上面這句話非常重要,請(qǐng)?jiān)谛睦镏貜?fù)一百遍。


  上面這句話非常重要,請(qǐng)?jiān)谛睦镏貜?fù)一百遍。


  上面這句話非常重要,請(qǐng)?jiān)谛睦镏貜?fù)一百遍。


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


  因此,在flask中,route是Flask類(lèi)的一個(gè)裝飾器。


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


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


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


  在http請(qǐng)求時(shí),F(xiàn)lask這個(gè)middleware負(fù)責(zé)完成對(duì)url對(duì)應(yīng)的處理函數(shù)的調(diào)用;


  那么,如果是我們自己來(lái)實(shí)現(xiàn)route,思路也很簡(jiǎn)單:


  建立一個(gè)類(lèi)Flask,這個(gè)類(lèi)是一個(gè)middleware,并且有一個(gè)字典型的成員變量url_map;


  url_map={url:function}


  當(dāng)http請(qǐng)求時(shí),進(jìn)行request dispatch:根據(jù)url,從url_map中找到function,然后調(diào)用function;


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


  flask的實(shí)現(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)用對(duì)象
  self.dispatch_request()#Flask的核心功能request dispatch
  return application(environ,start_response)#最后調(diào)用下一級(jí)的application
  def route(self,rule):#Flask使用裝飾器來(lái)完成url與處理函數(shù)的映射關(guān)系建立
  def decorator(f):#簡(jiǎn)單,侵入小,優(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中找到對(duì)應(yīng)的處理函數(shù),并調(diào)用


  至此,一個(gè)簡(jiǎn)單的Flaskmiddleware的骨架就完成了。


  上面的Flask類(lèi)主要功能包括:


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


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


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


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


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


  需要指出,上面實(shí)現(xiàn)的最簡(jiǎn)單的Flask類(lèi)還是有很多問(wèn)題的。


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


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


  首先需要簡(jiǎn)單了解一下Map和Rule的作用:


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


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


  其實(shí)現(xiàn)如下:


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


  這里需要解釋一下endpoint:


  前面說(shuō)過(guò):url與其處理函數(shù)可以使用一個(gè)字典來(lái)實(shí)現(xiàn):{url:function}


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


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


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


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


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


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


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


  因?yàn)椋拷⒁粋€(gè)url-->endpoint-->function關(guān)系就會(huì)創(chuàng)建一個(gè)Rule對(duì)象,所以,會(huì)有很多Rule對(duì)象存在。


  Map的作用則是保存所有Rule對(duì)象。


  所以,一般情況下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-->function


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


  成員變量view_functions保存所有的{endpoint,function}關(guān)系


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


  route的完整流程


  首先,建立Flask對(duì)象:


 app=Flask(__name__)


  然后,建立url與function之間的映射關(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)系


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


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

  app.run()


  調(diào)用python標(biāo)準(zhǔn)庫(kù)提供的WSGI server,在實(shí)際使用時(shí),可能是gunicorn或uwsgi。


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


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


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


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


  總結(jié)


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


  綜上所述,這篇文章就給大家介紹到這里了,希望可以給大家?guī)?lái)幫助。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/128315.html

相關(guān)文章

  • flask route設(shè)計(jì)思路

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

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

    小編寫(xiě)這篇文章的主要目的,主要是來(lái)給大家做出一個(gè)比較詳細(xì)解答,主要是給大家解答關(guān)于python中的一些知識(shí),比如Flask實(shí)現(xiàn)接手與上傳圖片,下面就給大家詳細(xì)解答下。  接下來(lái)給搭建講解Flask如何接受圖片文件,上面是復(fù)雜寫(xiě)法,下面是簡(jiǎn)單寫(xiě)法,二選一即可。  思路整理:接收?qǐng)D片->定義一個(gè)圖片存放的位置->給圖片重命名(為了唯一性)->保存操作-&...

    89542767 評(píng)論0 收藏0
  • 從零開(kāi)始搭建論壇(一):Web服務(wù)器與Web框架

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

    dantezhao 評(píng)論0 收藏0
  • [貳]Flask web開(kāi)發(fā):程序的基本結(jié)構(gòu)

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

    maxmin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<