循环引用
Flask框架超级灵活,给了用户很大的自由度,但是很多时候缺少约束的东西会让新手变得手足无措,比如用包组织代码是否遇到的循环引用问题:
# project/app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from models.User import User
app = Flask(__name__)
db = SQLAlchemy(app)
@app.route('/index')
def index():
user = User()
return "Hi"
if __name__ == "__main__":
app.run()
# project/models/User.py
from app import db
class User(db.Model):
nickName = db.Column(db.String(50))
当你运行app.py的时候,你会发现Python解释器会报错:
ImportError: cannot import name 'User' from 'models.User'
为什么?
在app.py中导入了User.py中的User,而User.py导入了app.py中的db,因此出现了循环应用:
User->db->User->...
app.py->User.py->app.py->...
解决办法
把导入冲突的包放在最后导入
把from models.User import User
放在app.py的最后面就解决了
然而这种方法把导入放在最后并不是很好看
使用工程函数
使用工厂函数对各个实例进行统一初始化:
# project/app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from views.index import indexbp
db = SQLAlchemy()
def create_app():
app = Flask("project")
db.init_app(app)
app.register_blueprint(indexbp)
return app
if __name__ == "__main__":
app = create_app()
app.run()
# project/views/index.py
from flask import Blueprint
indexbp = Blueprint("indexbp", "project")
from project.models.User import User
@indexbp.route('/')
def index():
user = User()
return "Hi"
# project/models/User.py
from project.app import db
class User(db.Model):
nickName = db.Column(db.String(50),primary_key=True)