Python Flask框架路由的簡單實現
也許你聽說過Flask框架。也許你也使用過,也使用的非常好。但是當你在瀏覽器上輸入一串路由地址,跳轉至你所寫的頁面,在Flask中是怎樣實現的,你是否感到好奇? 如果你不清楚,那就往下看看吧 ~
Flask demo代碼
from flask import Flask app = Flask(__name__)
@app.route('/') def hello_world(): return '<a href="/home">Hello World!</a>'
@app.route("/home") def home(): return "這個是主頁"
@app.route("/login") def login(): return "這個是登錄" if __name__ == '__main__': app.run(debug=True)
當你在瀏覽器地址上輸入路徑,進入不同視圖函數。
1.輸入路徑為:"/"
2.輸入路徑為:"/home"
3.輸入路徑為:"/login"
是不是很神奇~ 接下來讓我們看看他是如何實現的吧!
Flask原理
- 當啟動 app.run()后, @app.route()裝飾器會將 路徑信息、函數信息 傳入 self.add_url_rule(rule, endpoint, f, **options)
- self.add_url_rule(rule,endpoint, f,**potions) 接收到路徑信息、函數信息封裝打包放進全局的 self.url_map.add(rule)
- 這個時候的全局的self.url_map里面的信息為
- 當請求url進來會到 self.url_map匹配然后執行相應的方法函數,返回相應的方法結果。知道是這樣的流程 我們就可以得到下面的結果
簡單實現(廢話不多說,直接上碼!)
"""
Flask 路由簡單實現
map: {"/home":"home", "/login":"login", ...}
"""
map = dict()
def route(path):
def decorator(f):
print(path, f.__name__, "<-----------start---------->")
map[path] = f.__name__
return f
return decorator
class TestFlaskRoute:
def __init__(self, path):
self.path = path
def find_url(self):
try:
getattr(TestFlaskRoute, map.get(self.path)).__call__(self)
except:
print("\033[031m 沒有這個路徑! \033[0m ")
@route("/login")
def login(self, *args, **kwargs):
print("\033[036m 這個是登錄! \033[0m")
pass
@route("/home")
def home(self, *args, **kwargs):
print("\033[036m 這個是主頁! \033[0m")
pass
@route("/")
def index(self, *args, **kwargs):
print("\033[036m Hello World! \033[0m")
pass
@route("/call")
def phone(self, *args, **kwargs):
print("\033[036m 這個是", self.path, "! \033[0m")
pass
if __name__ == '__main__':
while True:
url = input("請輸入URL路徑:")
app = TestFlaskRoute(url)
app.find_url()
在這里我們用模擬瀏覽器輸入方式來完成,當我們輸入"/",它會去找對應路徑下 index() 執行 ; 輸入"/home",它會去找對應路徑下 home() 執行;輸入"/login", 它會去找對應路徑下 login() 執行,怎樣是不是很神奇,是不是很像Flask。其實Flask就是這樣的思路實現的。
效果:
解析實現(3步)
a.當程序啟動時, 先執行了route()這個裝飾器,拿到了所有路徑、對應函數並將它們存在map這個字典中,以路徑為key, 對應函數名為value。(注:在Flask是用全局 self.url_map 來存這些路由方法信息的哦,我們這里簡單實現用的是字典,所以還是有些區別的~)
b.當你輸入路徑或者在瀏覽器上輸入路徑,會以key的形式到map字典中匹配,取出value(函數名)。
c. 得到value通過getattr()得到函數地址, 然后用內置__call__()方法,執行這個函數
結束語
明白了Flask路由實現原理了嗎,如果有錯誤的地方歡迎評論下方指出!