4

Flask中处理依赖的技巧

 2 years ago
source link: https://blog.guyskk.com/notes/Flask%E4%B8%AD%E5%A4%84%E7%90%86%E4%BE%9D%E8%B5%96%E7%9A%84%E6%8A%80%E5%B7%A7
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Flask中处理依赖的技巧

2016年, 7月30日

Flask应用中通常会用工厂模式 来创建应用对象,这样方便配置和测试。

# app/__init__.py
from flask import Flask
from flask_xxxext import Xxx
from 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)
# manage.py
from app import create_app

app = create_app()

if __name__ == "__main__":
    app.run()
# test_app.py
from app import create_app

def test_xxx():
    app = create_app()
    # ... tests

在稍大一些的项目里,不可避免会用到许多flask插件,也会用到一些其他的库, 这些库通常没有特意去支持flask的应用工厂模式。

应用代码不仅依赖于这些外部的库,也会产生一些相互依赖。比如A模块依赖B模块,B模块又依赖A模块, 这样在导入模块的时候就会遇到循环导入的问题,有时还会产生A依赖B,B依赖C…N依赖A这样复杂的依赖关系。

一方面就是应用架构的问题,要解决这类依赖问题,首先是要让整体架构清晰,各个模块直接形成清晰的 职责边界,不要在同一个模块做职责不同的事。 比如A模块依赖B模块,B模块又依赖A模块,这种情况就是A模块或B模块做了职责之外的事,把它们 职责之外的事拆分出来,放到C模块中,问题就解决了。

另一方面就是使用全局对象带来的依赖问题,flask中通常会定义一些全局对象,在要用到的地方 直接导入需要的对象,这样使用的时候很方便。flask的插件基本都支持这样用,因为这些插件都没有 显式的依赖,而是提供一个init_app方法,用于在运行时初始化插件。

但是还会用到一些其他的库,这些库没有提供init_app方法。 有两种办法,第一种就是写一个新的类,把原来的库包装一下,提供一个init_app方法用来延迟初始化。 这种方法有点繁琐,也不灵活,对每一个依赖都要写一个类。

另一种方法就是用 werkzeug.local.LocalProxy 实现延迟初始化。

所有被依赖的全局对象

# app/dependency.py
from werkzeug.local import LocalProxy


class Dependency:
    """Dependency"""

d = Dependency()
xx = LocalProxy(lambda: d.xx)
yy = LocalProxy(lambda: d.yy)

__all__ = ['d', 'xx', 'yy']
# app/__init__.py
from xxx import Xxx
from yyy import Yyy
from dependency import d

def create_app(config=None):
    app = create_app()
    d.xx = Xxx(...)
    d.yy = Yyy(...)
# app/some_module.py
from .dependency import xx

def view():
    # 业务代码
    xx.xxxx()

使用这种方式方便又灵活,唯一的限制是被依赖的全局对象只能在应用初始化之后使用,不过这些业务代码都是 在接受到请求才会执行,这时候应用早就初始化了,所以这点限制也没什么影响。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK