Flask文件结构
我正在做一个中等规模的Flask应用程序。这个应用有两个主要模块,一个是用来创建数据库的,我们叫它schema.py,另一个是提供视图的,叫views.py。我按照Flask的推荐结构来组织我的代码。
在__init__.py
文件中,我定义了app
和db=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 个回答
来自 http://flask.pocoo.org/docs/patterns/packages/ 的内容(增加了高亮)
每个Python程序员都讨厌循环导入,但我们刚刚添加了一些:循环导入就是两个模块互相依赖。在这个例子中,views.py依赖于
__init__.py
。要注意,这通常是个坏主意,但在这里其实没问题。原因是我们并没有在__init__.py
中真正使用views,只是确保模块被导入,而我们是在文件的底部这样做的。
确保 import myapp.views
放在 __init__.py
的底部,也就是在定义完 app
和 db
之后。虽然这违反了 pep8的规范,但正如上面所说的,这里其实是可以的。
在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(...)
哦,是的,我们也遇到过循环导入的问题,不过解决这个问题的一种方法是创建应用工厂,具体可以参考文档。
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
如果你想的话,可以把组件放在另一个模块里,这样可以让它们更分开,但我们发现这是一种最简单的方法,可以“帮助”避免循环导入的问题。