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

Python的Flask框架中@app.route的用法教程

 更新時(shí)間:2015年03月31日 11:57:03   作者:Ainsley  
這篇文章主要介紹了Python的Flask框架中@app.route的用法教程,包括相關(guān)的正則表達(dá)式講解,是Flask學(xué)習(xí)過程當(dāng)中的基礎(chǔ)知識,需要的朋友可以參考下

在我上一篇文章,我搭了一個(gè)框架,模擬了Flask網(wǎng)站上“@app.route(‘/')”第一條例子的行為。

如果你錯(cuò)過了那篇“這不是魔法”,請點(diǎn)擊這里。

在這篇文章中,我們打算稍微調(diào)高點(diǎn)難度,為我們的URL加入可變參數(shù)的能力,在本文的最后,我們將支持下述代碼段所期望達(dá)到的行為。

 
app = Flask(__name__)
 
@app.route("/hello/<username>")
def hello_user(username):
  return "Hello {}!".format(username)

這樣下面的路徑實(shí)例(path):
/hello/ains
將會匹配上面的路徑,給我們的輸出為
Hello ains!

以正則的形式表達(dá)我們的路徑。

現(xiàn)在我們將允許我們的URL動態(tài)變化,我們不再能夠?qū)⒂孟惹笆褂谩癅app.route()”注冊的路徑直接與路徑實(shí)例比較。

我們將用什么替代?我們需要用上正則表達(dá)式,這樣我們就可以將路徑作為一種模式進(jìn)行匹配,而不和一條固定的字符串比較了。

我不打算在本文展開討論正則表達(dá)式的細(xì)節(jié),不過如果你需要一份復(fù)習(xí)資料,可以點(diǎn)擊這個(gè)網(wǎng)站。

那么,我們的第一步是將我們的路徑轉(zhuǎn)化成正則表達(dá)式模式,這樣我們就能在輸入路徑實(shí)例時(shí)進(jìn)行匹配。我們也將使用這個(gè)正則表達(dá)式提取我們感興趣的變量。

那么,匹配路徑”/hello/”的正則表達(dá)式該長啥樣呢?

嗯一個(gè)簡單的正則表達(dá)式譬如“^/hello/(.+)$”將是個(gè)好的開始,讓我們一起看看它和代碼是怎么一起工作的:

 
import re
 
route_regex = re.compile(r"^/hello/(.+)$")
match = route_regex.match("/hello/ains")
 
print match.groups()

將會輸出:
('ains',)

不錯(cuò),不過,理想情況是我們想要維護(hù)我們已經(jīng)匹配上的第一組鏈接,并且從路徑“/hello/”識別出“username”。

命名捕獲組

幸運(yùn)的是,正則表達(dá)式也支持命名捕獲組,允許我們給匹配組分配一個(gè)名字,我們能在讀取我們的匹配之后找回它。

我們可以使用下述符號,給出第一個(gè)例子識別“username”的捕獲組。
 

/hello/(<?P<username>.+)"

然后我們可以對我們的正則表達(dá)式使用groupdict()方法,將所有捕獲組當(dāng)作一個(gè)字典,組的名字對應(yīng)匹配上的值。

那么我們給出下述代碼:
 

route_regex = re.compile(r'^/hello/(?P<username>.+)$')
match = route_regex.match("/hello/ains")
 
print match.groupdict()

將為我們輸出以下字典:
{'username': 'ains'}

現(xiàn)在,有了我們所需要的正則表達(dá)式的格式,以及如何使用它們?nèi)テヅ漭斎氲腢RLs的知識,最后剩下的是寫一個(gè)方法,將我們聲明的路徑轉(zhuǎn)換成它們等價(jià)的正則表達(dá)式模式。

要做這個(gè)我們將使用另一個(gè)正則表達(dá)式(接下來將全是正則表達(dá)式),為了讓我們路徑中的變量轉(zhuǎn)換成正則表示式模式,那這里作為示范我們將將“”轉(zhuǎn)換成“(?P.+)”。

聽起來太簡單了!我們將可以只用一行新代碼實(shí)現(xiàn)它。

 
def build_route_pattern(route):
  route_regex = re.sub(r'(<w+>)', r'(?P1.+)', route)
  return re.compile("^{}$".format(route_regex))
 
print build_route_pattern('/hello/<username>')

這里我們用一個(gè)正則表達(dá)式代表所有出現(xiàn)的模式(一個(gè)包含在尖括號中的字符串),與它的正則表達(dá)式命名組等價(jià)。

re.sub的第一個(gè)參數(shù) 我們將我們的模式放進(jìn)括號,目的是把它分配到第一個(gè)匹配組。在我們的第二個(gè)參數(shù),我們可以使用第一匹配組的內(nèi)容,方法是寫1(2將是第二匹配組的內(nèi)容,以此類推…….)

那么最后,輸入模式
 

/hello/<username>

將給我們正則表達(dá)式:
 

^/hello/(?P<username>.+)$

推陳出新

讓我們掃一眼上次我們寫的簡單NotFlask類。
 

class NotFlask():
  def __init__(self):
    self.routes = {}
 
  def route(self, route_str):
    def decorator(f):
      self.routes[route_str] = f
      return f
 
    return decorator
 
  def serve(self, path):
    view_function = self.routes.get(path)
    if view_function:
      return view_function()
    else:
      raise ValueError('Route "{}"" has not been registered'.format(path))
 
app = NotFlask()
 
@app.route("/")
def hello():
  return "Hello World!"

現(xiàn)在我們有一個(gè)新的改進(jìn)方法用來匹配輸入的路徑,我們打算移除我們上一版實(shí)現(xiàn)時(shí)用到的原生字典。

讓我們從改造我們的函數(shù)著手,以便于添加路徑,這樣我們就可以用(pattern, view_function)對列表代替字典保存我們的路徑。

這意味著當(dāng)一個(gè)程序員使用@app.route()裝飾一個(gè)函數(shù),我們將要嘗試將他們的路徑編譯變成一個(gè)正則表達(dá)式,然后存儲它,屬于一個(gè)在我們新的路徑列表里的裝飾函數(shù)。

讓我們看看實(shí)現(xiàn)代碼:

 
class NotFlask():
  def __init__(self):
    self.routes = []
 
  # Here's our build_route_pattern we made earlier
  @staticmethod
  def build_route_pattern(route):
    route_regex = re.sub(r'(<w+>)', r'(?P1.+)', route)
    return re.compile("^{}$".format(route_regex))
 
  def route(self, route_str):
    def decorator(f):
      # Instead of inserting into a dictionary,
      # We'll append the tuple to our route list
      route_pattern = self.build_route_pattern(route_str)
      self.routes.append((route_pattern, f))
 
      return f
 
    return decorator

我們也打算需要一個(gè)get_route_match方法,給它一個(gè)路徑實(shí)例,將會嘗試并找到一個(gè)匹配的view_function,或者返回None如果一個(gè)也找不到的話。

然而,如果找了到匹配的話,除了view_function之外,我們還需要返回一個(gè)東西,那就是我們包含之前捕獲匹配組的字典,我們需要它來為視圖函數(shù)傳遞正確的參數(shù)。

好了我們的get_route_match大概就長這樣:

 
def get_route_match(path):
  for route_pattern, view_function in self.routes:
    m = route_pattern.match(path)
    if m:
      return m.groupdict(), view_function
 
  return None

現(xiàn)在我們快要完成了,最后一步將是找出調(diào)用view_function的方法,使用來自正則表達(dá)式匹配組字典的正確參數(shù)。

調(diào)用一個(gè)函數(shù)的若干種方法

讓我們回顧一下不同的方法調(diào)用一個(gè)python的函數(shù)。

比如像這樣:

 
def hello_user(username):
  return "Hello {}!".format(username)

最簡單的(也許正是你所熟知的)辦法是使用正則參數(shù),在這里參數(shù)的順序匹配我們定義的那些函數(shù)的順序。

>>> hello_user("ains")
Hello ains!

另一種方法調(diào)用一個(gè)函數(shù)是使用關(guān)鍵詞參數(shù)。關(guān)鍵詞參數(shù)可以通過任何順序指定,適合有許多可選參數(shù)的函數(shù)。

>>> hello_user(username="ains")
Hello ains!

在Python中最后一種調(diào)用一個(gè)函數(shù)的方法是使用關(guān)鍵詞參數(shù)字典,字典中的關(guān)鍵詞對應(yīng)參數(shù)名稱。我們告訴Python解包一個(gè)字典,并通過使用兩個(gè)星號“**”來把它當(dāng)作函數(shù)的關(guān)鍵詞參數(shù)。 下面的代碼段與上面的代碼段完全一樣,現(xiàn)在我們使用字典參數(shù),我們可以在運(yùn)行時(shí)動態(tài)創(chuàng)建它。

>>> kwargs = {"username": "ains"}
>>> hello_user(**kwargs)
Hello ains!

好了,還記得上面的groupdict()方法?就是那個(gè)同樣的在正則表達(dá)式完成匹配后返回{“username”: “ains”}的家伙?那么現(xiàn)在我們了解了kwargs,我們能很容易向我們的view_function傳遞字典匹配,完成NotFlask!

那么讓我們把這些都塞進(jìn)我們最終的類中。
 

class NotFlask():
  def __init__(self):
    self.routes = []
 
  @staticmethod
  def build_route_pattern(route):
    route_regex = re.sub(r'(<w+>)', r'(?P1.+)', route)
    return re.compile("^{}$".format(route_regex))
 
  def route(self, route_str):
    def decorator(f):
      route_pattern = self.build_route_pattern(route_str)
      self.routes.append((route_pattern, f))
 
      return f
 
    return decorator
 
  def get_route_match(self, path):
    for route_pattern, view_function in self.routes:
      m = route_pattern.match(path)
      if m:
        return m.groupdict(), view_function
 
    return None
 
  def serve(self, path):
    route_match = self.get_route_match(path)
    if route_match:
      kwargs, view_function = route_match
      return view_function(**kwargs)
    else:
      raise ValueError('Route "{}"" has not been registered'.format(path))

接下來,就是見證奇跡的時(shí)刻,請看下面代碼段:

 
app = NotFlask()
 
@app.route("/hello/")
def hello_user(username):
return "Hello {}!".format(username)
 
print app.serve("/hello/ains")

我們將得到輸出:

Hello ains!

相關(guān)文章

  • Python遠(yuǎn)程SSH庫Paramiko詳細(xì)操作

    Python遠(yuǎn)程SSH庫Paramiko詳細(xì)操作

    paramiko實(shí)現(xiàn)了SSHv2協(xié)議(底層使用cryptography),用于連接遠(yuǎn)程服務(wù)器并執(zhí)行相關(guān)操作,使用該模塊可以對遠(yuǎn)程服務(wù)器進(jìn)行命令或文件操作,今天通過本文給大家介紹Python遠(yuǎn)程SSH庫Paramiko簡介,感興趣的朋友一起看看吧
    2022-05-05
  • python使用cPickle模塊序列化實(shí)例

    python使用cPickle模塊序列化實(shí)例

    這篇文章主要介紹了python使用cPickle模塊序列化的方法,是一個(gè)非常實(shí)用的技巧,需要的朋友可以參考下
    2014-09-09
  • ubuntu上安裝python的實(shí)例方法

    ubuntu上安裝python的實(shí)例方法

    在本篇文章里小編給大家整理的是關(guān)于怎么在ubuntu安裝python的相關(guān)方法,以后需要的朋友們可以學(xué)習(xí)下。
    2019-09-09
  • python編寫簡單爬蟲資料匯總

    python編寫簡單爬蟲資料匯總

    本文給大家匯總介紹了下幾種使用Python編寫簡單爬蟲的方法和代碼,非常的不錯(cuò),這里分享給大家,希望大家能夠喜歡。
    2016-03-03
  • python format 格式化輸出方法

    python format 格式化輸出方法

    今天小編就為大家分享一篇python format 格式化輸出方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • python3 sqlite3限制條件查詢的操作

    python3 sqlite3限制條件查詢的操作

    這篇文章主要介紹了python3 sqlite3限制條件查詢的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Python3.5面向?qū)ο蟪绦蛟O(shè)計(jì)之類的繼承和多態(tài)詳解

    Python3.5面向?qū)ο蟪绦蛟O(shè)計(jì)之類的繼承和多態(tài)詳解

    這篇文章主要介紹了Python3.5面向?qū)ο蟪绦蛟O(shè)計(jì)之類的繼承和多態(tài),結(jié)合實(shí)例形式詳細(xì)分析了Python3.5面向?qū)ο蟪绦蛟O(shè)計(jì)中類的繼承與多態(tài)常見用法及相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2019-04-04
  • python批量獲取html內(nèi)body內(nèi)容的實(shí)例

    python批量獲取html內(nèi)body內(nèi)容的實(shí)例

    今天小編就為大家分享一篇python批量獲取html內(nèi)body內(nèi)容的實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-01-01
  • pycharm打包py項(xiàng)目為.exe可執(zhí)行文件的兩種方式

    pycharm打包py項(xiàng)目為.exe可執(zhí)行文件的兩種方式

    本文主要介紹了pycharm打包py項(xiàng)目為.exe可執(zhí)行文件的兩種方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • python中Class(類)的超詳細(xì)說明

    python中Class(類)的超詳細(xì)說明

    這篇文章主要介紹了python中Class(類)的相關(guān)資料,Class類定義了具有相同屬性和方法的對象集合,對象是類的實(shí)例,類變量在整個(gè)實(shí)例化的對象中是公用的,而實(shí)例變量是每個(gè)對象獨(dú)有的,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-11-11

最新評論

察雅县| 施秉县| 荣成市| 吉首市| 汕尾市| 德保县| 汕尾市| 南投市| 通江县| 新兴县| 收藏| 商丘市| 高清| 宁河县| 雅江县| 永兴县| 邵阳市| 洛南县| 华亭县| 巴青县| 和田县| 平安县| 青铜峡市| 澄江县| 巧家县| 托克托县| 洪江市| 柯坪县| 望奎县| 富阳市| 平阳县| 新源县| 梁河县| 南阳市| 石门县| 和顺县| 哈密市| 海门市| 剑河县| 扶余县| 改则县|