欢迎加入QQ讨论群258996829
麦子学院 头像
苹果6袋
6
麦子学院

Flask中如何处理依赖

发布时间:2016-08-17 22:08  回复:0  查看:2233   最后回复:2016-08-17 22:08  

Flask应用中通常会用工厂模式 来创建应用对象,这样方便配置和测试。现在我们就用实例来学习Flask的处理依赖

应用代码

# 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)

启动脚本

# manage.pyfrom app import create_app

app = create_app()

if __name__ == "__main__":

    app.run()

测试代码

# test_app.pyfrom 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.pyfrom werkzeug.local import LocalProxy


class Dependency:

    """Dependency"""

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

__all__ = [’d’, ’xx’, ’yy’]

应用代码

# 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():

    # 业务代码

    xx.xxxx()

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

 

文章来自:黄康德的博客

您还未登录,请先登录

热门帖子

最新帖子