Flask2.0重要改動
據JetBrains Python開發者社區調查,Flask是近年來最常用的Python Web開發框架之一。Flask2.0.0
於2021年5月份發布,共推出了三十多個版本變更,主要變更如下:
三大核心特性
- 嵌套藍圖
- 異步視圖
- 快捷路由裝飾器
其他重要變化
- 不再支持Python2和Python3.5
- 新增了Type hinting,有助於IDE自動補全
- 支持從任意文件加載器導入配置(導入方法為
Config.from_file()
) - 優化瀏覽器緩存控制,靜態文件變動后,重啟應用會立即更新資源(不再需要手動清緩存)
- Werkzeug的multipart解析性能提高了15倍
jsonify
支持序列化decimal.Decimal
格式的數據(該改動在Flask2.0.2版本添加)
安裝
本文使用Python3.9(部分特性需要3.9以上版本支持)
pip install -U flask
若是想用Flask2.0的異步功能,則需要安裝額外依賴(主要是asgiref
包)
pip install -U flask[async]
三大核心特性講解
上面我列出了Flask2.0新增的三大核心特性,接下來我會通過代碼來說明這三大特性的特點和使用方法,並嘗試根據這三大特性來編寫一個簡單的應用。
嵌套藍圖
Flask使用藍圖Blueprint對程序進行模塊化處理。一個大型項目通常都會使用藍圖來規划不同的模塊,而嵌套藍圖的作用就是可以更細地去划分管理不同的模塊。
一個應用可以注冊多個藍圖,而現在藍圖也可以注冊多個子藍圖(子藍圖還可以注冊孫子藍圖,可以嵌套很多層,支持無限嵌套),對項目進行多層模塊化組織。
app = Flask(__name__) # 創建一個應用
a = Blueprint('a', __name__) # 創建父藍圖
b = Blueprint('b', __name__) # 創建子藍圖
a.register_blueprint(b) # 將子藍圖注冊到父藍圖上
app.register_blueprint(a) # 將父藍圖注冊到應用上
上面例子只是簡單示范嵌套藍圖的使用,實際開發中一般不會將應用和藍圖寫到同一個文件內。
異步視圖
Flask2.0加入了基本的async/await支持(目前只是基於asgiref來實現異步),因此我們可以自己去定義異步視圖。
異步視圖有很多優點,比如能夠在不使用Python線程的情況下為數百個連接提供服務,允許使用慢速流、長輪詢和其他的響應類型等等。
import asyncio
from flask import Flask
app = Flask(__name__)
@app.route('/')
async def hello():
await asyncio.sleep(1)
return 'hello flask'
if __name__ == '__main__':
app.run()
快捷路由裝飾器
新增了以下路由裝飾器:
- app.get()
- app.post()
- app.delete()
- app.put()
- app.patch()
上面的路由裝飾器對應之前的app.route()
裝飾器,如app.post()
相當於app.route(methods=['POST'])
。需要注意的是,這些快捷路由裝飾器只能處理單個方法類型的請求,如果需要處理多種方法類型的請求,請用app.route()
裝飾器。
from flask import Flask
app = Flask(__name__)
@app.post('/hello') # 快捷路由裝飾器
def hello():
return 'Hello Flask'
@app.route('/hello2', methods=['GET', 'POST']) # 多種請求類型
def hello2():
return 'Hello Flask2'
if __name__ == '__main__':
app.run()
創建一個簡單的項目
在了解了Flask2.0的一些新功能和新特性后,我們來嘗試使用這些新特性創建一個簡單的項目
該項目上創建一個應用,應用上注冊了兩個藍圖,分別為v1
和v2
(代表兩個不同的版本),v1藍圖和v2藍圖上分別注冊了子藍圖admin
和user
,v1版本的視圖函數使用以往的寫法,v2版本的視圖函數使用新的特性,以便大家進行對比。
項目的目錄結構如下
flask2
/app
/v1
__init__.py
admin.py
user.py
/v2
__init__.py
admin.py
user.py
__init__.py
manager.py
manager.py文件用於啟動我們的Web服務
from flask import Flask
from app import v1, v2
app = Flask(__name__) # 創建Flask的主app
app.register_blueprint(v1.bp) # 注冊藍圖
app.register_blueprint(v2.bp)
@app.route('/')
def index():
return 'Hello World'
if __name__ == '__main__':
app.run(debug=True)
/app/v1/__init__.py,該文件主要用於加載項目包時創建父藍圖和注冊子藍圖
from flask import Blueprint
from app.v1 import admin, user
bp = Blueprint('v1', __name__, url_prefix='/v1') # 創建父藍圖v1
bp.register_blueprint(admin.api) # 注冊子藍圖admin
bp.register_blueprint(user.api) # 注冊子藍圖user
@bp.route('')
def index():
"""父藍圖視圖函數"""
return 'here is v1.'
/app/v1/admin.py
from flask import Blueprint
api = Blueprint('admin', __name__, url_prefix='/admin') # 創建一個藍圖
@api.route('')
def index():
return 'here is admin v1.'
@api.route('/hello', methods=['POST'])
def hello():
return 'hello admin v1'
/app/v1/user.py
from flask import Blueprint
api = Blueprint('user', __name__, url_prefix='/user') # 創建一個藍圖
@api.route('')
def index():
return 'here is user v1.'
@api.route('/hello', methods=['GET', 'POST']) # 多種請求類型
def hello():
return 'hello user v1.'
/app/v2/__init__.py
from flask import Blueprint
from app.v2 import admin, user
bp = Blueprint('v2', __name__, url_prefix='/v2') # 創建父藍圖v2
bp.register_blueprint(admin.api) # 注冊子藍圖admin
bp.register_blueprint(user.api) # 注冊子藍圖user
@bp.route('')
def index():
"""父藍圖視圖函數"""
return 'here is v2.'
/app/v2/admin.py
import asyncio
from flask import Blueprint
api = Blueprint('admin', __name__, url_prefix='/admin') # 創建一個藍圖
@api.get('') # 快捷路由裝飾器
def index():
return 'here is admin v2.'
@api.post('/hello')
async def hello():
"""異步視圖"""
await asyncio.sleep(1)
return 'hello admin v2.'
/app/v2/user.py
import asyncio
from flask import Blueprint
api = Blueprint('user', __name__, url_prefix='/user') # 創建一個藍圖
@api.get('')
def index():
return 'here is user v2.'
@api.post('/hello')
async def hello():
await asyncio.sleep(1)
return 'hello user v2.'
項目代碼我放到我的Github上,有需要的話可以去上面取。
代碼編寫完后運行manager.py文件啟動項目,項目url為 http://localhost:5000
可以使用python
或者Postman
軟件來發送相關的請求,如發送一個GET請求到 http://localhost:5000/v1/user
,或者發送一個POST請求到 http://localhost:5000/v2/user/hello
,會返回相關的數據。(如果返回的結果是404或405,則注意是否url或者請求方法錯了)
以上就是Flask2.0的新特性介紹,如果想學習更多關於Flask的知識點,可以去Flask官方文檔中查閱。