使用Flask蓝图解决此循环导入错误的正确方法是什么?

时间:2015-06-10 15:51:41

标签: python flask

我的循环导入出了问题,所以我将蓝图导入移到了我的应用定义之下。但是,我仍然遇到导入错误。

Traceback (most recent call last):
  File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 2217, in <module>
    globals = debugger.run(setup['file'], None, None)
  File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydevd.py", line 1643, in run
    pydev_imports.execfile(file, globals, locals)  # execute the script
  File "/Users/benjamin/Documents/Projects/website/server/app/app.py", line 15, in <module>
    from views import site
  File "/Users/benjamin/Documents/Projects/website/server/app/views.py", line 2, in <module>
    from models import User
  File "/Users/benjamin/Documents/Projects/website/server/app/models.py", line 3, in <module>
    from database_setup import db
  File "/Users/benjamin/Documents/Projects/website/server/app/database_setup.py", line 1, in <module>
    from app import app
  File "/Users/benjamin/Documents/Projects/website/server/app/app.py", line 15, in <module>
    from views import site
ImportError: cannot import name site

如果我将蓝图导入和注册移至if __name__ == '__main__':,问题就会消失,但我不确定这是不是一个好主意。

if __name__ == '__main__':
    from views import site
    app.register_blueprint(site)
    app.run()

这是解决问题的正确方法,还是有其他解决方案?

原始app.py没有__main__“修复”:

from flask import Flask

app = Flask(__name__)

from views import site
app.register_blueprint(site)

if __name__ == '__main__':
    app.debug = True
    app.run()

views.py

from flask import Blueprint, render_template

site = Blueprint('site', __name__, template_folder='templates', static_folder='static')

@site.route('/', methods=['GET', 'POST'])
def index():
    return render_template('index.html')

database_setup.py

from app import app
from flask_mongoengine import MongoEngine

app.config['MONGODB_SETTINGS'] = {'db': 'mst_website'}    
db = MongoEngine(app)

models.py

from database_setup import db

class User(db.Document):
    # ...

我的文件结构是:

/server
  |-- requirements.txt
  |-- env/ (virtual environment)
  |-- app/ (my main app folder)
       |-- static/
       |-- templates/
       |-- __init__.py
       |-- app.py
       |-- database_setup.py
       |-- models.py
       |-- views.py

1 个答案:

答案 0 :(得分:3)

您的代码中包含循环导入。基于追溯:

  1. app.py执行from views import site
  2. views.py执行from models import User
  3. models.py执行from database_setup import db
  4. database_setup.py执行from app import app
  5. app.py执行from views import site
  6. 根据这些事件顺序,您发布的app.py不是实际导致问题的那个。目前,在导入app之前尚未定义views,因此当进一步向下链接时,它会尝试获取app,但它尚未可用。

    您需要重新构建项目,以便在定义 app后导入依赖于app的所有内容。从您的问题来看,您似乎认为自己已经这样做了,但也许还有一个上面写的app导入的错误。

    可能不相关,但您目前正在使用“相对”导入,这是不鼓励的。您不应该执行from views import site等,而应该执行绝对路径:from app.views import site或相对路径:from .views import site

    回答最初的问题“正在使用__main__导入蓝图是一个好主意吗?”,事实并非如此。问题在于,当您直接运行模块时,__main__防护仅执行 。当您使用真实的应用服务器(如uWSGI或Gunicorn)进行部署时,您的蓝图都不会被导入或注册。