Flask應(yīng)用中通常會(huì)用工廠模式 來(lái)創(chuàng)建應(yīng)用對(duì)象,這樣方便配置和測(cè)試?,F(xiàn)在我們就用實(shí)例來(lái)學(xué)習(xí)Flask的處理依賴
應(yīng)用代碼
# app/__init__.pyfrom flask import Flaskfrom flask_xxxext import Xxxfrom flask_yyyext import Yyy# ... 一些flask拓展xx = Xxx()yy = Yyy()
def create_app(config=None):
app = Flask(__name__)
xx.init_app(app)
yy.init_app(app)
啟動(dòng)腳本
# manage.pyfrom app import create_app
app = create_app()
if __name__ == "__main__":
app.run()
測(cè)試代碼
# test_app.pyfrom app import create_app
def test_xxx():
app = create_app()
# ... tests
在稍大一些的項(xiàng)目里,不可避免會(huì)用到許多flask插件,也會(huì)用到一些其他的庫(kù), 這些庫(kù)通常沒(méi)有特意去支持flask的應(yīng)用工廠模式。
應(yīng)用代碼不僅依賴于這些外部的庫(kù),也會(huì)產(chǎn)生一些相互依賴。比如A模塊依賴B模塊,B模塊又依賴A模塊, 這樣在導(dǎo)入模塊的時(shí)候就會(huì)遇到循環(huán)導(dǎo)入的問(wèn)題,有時(shí)還會(huì)產(chǎn)生A依賴B,B依賴C…N依賴A這樣復(fù)雜的依賴關(guān)系。
一方面就是應(yīng)用架構(gòu)的問(wèn)題,要解決這類(lèi)依賴問(wèn)題,首先是要讓整體架構(gòu)清晰,各個(gè)模塊直接形成清晰的 職責(zé)邊界,不要在同一個(gè)模塊做職責(zé)不同的事。 比如A模塊依賴B模塊,B模塊又依賴A模塊,這種情況就是A模塊或B模塊做了職責(zé)之外的事,把它們 職責(zé)之外的事拆分出來(lái),放到C模塊中,問(wèn)題就解決了。
另一方面就是使用全局對(duì)象帶來(lái)的依賴問(wèn)題,flask中通常會(huì)定義一些全局對(duì)象,在要用到的地方 直接導(dǎo)入需要的對(duì)象,這樣使用的時(shí)候很方便。flask的插件基本都支持這樣用,因?yàn)檫@些插件都沒(méi)有 顯式的依賴,而是提供一個(gè)init_app方法,用于在運(yùn)行時(shí)初始化插件。
但是還會(huì)用到一些其他的庫(kù),這些庫(kù)沒(méi)有提供init_app方法。 有兩種辦法,第一種就是寫(xiě)一個(gè)新的類(lèi),把原來(lái)的庫(kù)包裝一下,提供一個(gè)init_app方法用來(lái)延遲初始化。 這種方法有點(diǎn)繁瑣,也不靈活,對(duì)每一個(gè)依賴都要寫(xiě)一個(gè)類(lèi)。
另一種方法就是用 werkzeug.local.LocalProxy 實(shí)現(xiàn)延遲初始化。
所有被依賴的全局對(duì)象
# app/dependency.pyfrom werkzeug.local import LocalProxy
class Dependency:
"""Dependency"""
d = Dependency()xx = LocalProxy(lambda: d.xx)yy = LocalProxy(lambda: d.yy)
__all__ = [’d’, ’xx’, ’yy’]
應(yīng)用代碼
# app/__init__.pyfrom xxx import Xxxfrom yyy import Yyyfrom dependency import d
def create_app(config=None):
app = create_app()
d.xx = Xxx(...)
d.yy = Yyy(...)
# app/some_module.pyfrom .dependency import xx
def view():
# 業(yè)務(wù)代碼
xx.xxxx()
使用這種方式方便又靈活,唯一的限制是被依賴的全局對(duì)象只能在應(yīng)用初始化之后使用,不過(guò)這些業(yè)務(wù)代碼都是 在接受到請(qǐng)求才會(huì)執(zhí)行,這時(shí)候應(yīng)用早就初始化了,所以這點(diǎn)限制也沒(méi)什么影響。
文章來(lái)自:黃康德的博客