循环引用

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)

标签: Flask, Python

添加新评论