Flask文件结构

2 投票
3 回答
1800 浏览
提问于 2025-04-17 13:47

我正在做一个中等规模的Flask应用程序。这个应用有两个主要模块,一个是用来创建数据库的,我们叫它schema.py,另一个是提供视图的,叫views.py。我按照Flask的推荐结构来组织我的代码。

__init__.py文件中,我定义了appdb=SQLAlchemy(app)。但是我遇到了循环导入的问题!下面是我的文件导入情况:

schema.py:

from myapp import db

views.py:

from myapp import app,db
import myapp.schema

__init__.py

import myapp.views

因此,当我运行schema.py时,就会出现循环导入的错误。我该如何解决这个问题呢?希望能得到一些建议。

3 个回答

1

来自 http://flask.pocoo.org/docs/patterns/packages/ 的内容(增加了高亮)

每个Python程序员都讨厌循环导入,但我们刚刚添加了一些:循环导入就是两个模块互相依赖。在这个例子中,views.py依赖于 __init__.py。要注意,这通常是个坏主意,但在这里其实没问题。原因是我们并没有在 __init__.py 中真正使用views,只是确保模块被导入,而我们是在文件的底部这样做的。

确保 import myapp.views 放在 __init__.py 的底部,也就是在定义完 appdb 之后。虽然这违反了 pep8的规范,但正如上面所说的,这里其实是可以的。

1

在Flask框架中,有一个叫做 g 的对象,还有一个叫做 current_app 的东西。简单来说,current_app 就是你在初始化应用时创建的那个应用,它代表了你的应用。只要你导入 from flask import current_app,就可以随时使用这个应用。虽然有一些限制,但如果你需要访问应用的设置,这个就非常有用。

至于 g,这是一个很好的地方,可以用来存放像数据库连接这样的东西,这样在你的应用的任何地方都能使用。如果你在 __init__.py 文件中有类似这样的代码:

from flask import g
g.db = connect_to_some_db(...)

那么在其他需要使用数据库连接的地方,你只需要简单地:

from flask import g
# do something with your db
g.db.some_method_or_whatever(...)
3

哦,是的,我们也遇到过循环导入的问题,不过解决这个问题的一种方法是创建应用工厂,具体可以参考文档。

http://flask.pocoo.org/docs/patterns/appfactories/

你还可以考虑创建一个新的模块,或者找个地方来放置组件。比如说,使用SQLAlchemy作为例子。

#: SQLalchemy object created without an attached app
db = SQLAlchemy()

def create_app():
    app = Flask(__name__)
    #: some configuration stuff

    #: Initializing app.
    db.init_app(app)

    return app

如果你想的话,可以把组件放在另一个模块里,这样可以让它们更分开,但我们发现这是一种最简单的方法,可以“帮助”避免循环导入的问题。

撰写回答