我正在按照本教程使用Python 2.7在Flask中构建用户登录系统。
Intro to Flask: Signing In and Out
我有这个Flask应用程序结构。
flaskapp/
└── app/
├── user/
│ ├── __init__.py
│ ├── static/
│ ├── templates/
│ ├── forms.py
│ ├── routes.py
└── runserver.py
在教程中,我让我编辑这个文件。
app/intro_to_flask/routes.py
在该文件中,您有此代码。
from user import app
from flask import render_template, request, flash
from forms import ContactForm
from flask.ext.mail import Message, Mail
mail = Mail()
.
.
.
# @app.route() mappings start here
我收到此错误。
ImportError: cannot import name app
话虽如此,我无法从用户导入应用程序做到。我试过了:
from . import app
我真的不知道如何在这里解释这个问题,但是我正在编辑用户目录中的python文件,该文件试图导入自身内部的外部目录?如果应用程序目录不在用户目录中,您如何从用户导入应用程序执行操作?我在这里缺少什么?
在runserver.py中,我能够这样做,因为我假设runserver.py存在于app目录中。我不能在routes.py中这样做。
如果我无法导入应用程序,我无法在Flask中定义路径:
@app.route('/')
def index():
return "Testing route!"
答案 0 :(得分:2)
在您链接到的教程中,app
在__init__.py
文件中定义,如下所示:
from flask import Flask
app = Flask(__name__)
# ... The tutorial has a lot more below this, too - it's all probably important.
模块中名为app
的变量(在教程中名为intro_to_flask
,在您的案例中名为user
)与名为app
的文件夹无关。
在__init__.py
中有正确的内容,我认为这样可以解决。
答案 1 :(得分:0)
这是您理解Python打包和导入系统如何工作的问题(据我所知)。您引用的教程使用了更简单的结构(两个文件中的所有内容)。
我会将您的结构简化为包含多个文件(模块)的单个包(文件夹)。以下是导入的工作原理。
from x import y
来自[此模块或包]导入[某事]"
模块=文件
包=文件夹(其中包含__init__.py
文件**必需)
您不能让一个模块从无法到达的模块导入某些内容。 (即无法找到的包裹)
您也不能进行循环导入。比如这个:
from x import y
a = 1
# ... and then inside x.py
from z import a
赢了。
希望这可以帮助您弄清楚导入问题的具体细节。
答案 2 :(得分:0)
在这里回答我自己的问题。
问题在于进口的顺序。我使用一种名为PyCharm的流行IDE,遵循PEP 8标准。它在重构期间将导入放在文件的顶部,这导致应用程序在导入时失败。
这是我重构的init.py文件的原始代码(PEP 8):
from flask import Flask
from routes import mail
import user.routes
app = Flask(__name__)
app.secret_key = 'development key'
app.config["MAIL_SERVER"] = "smtp.gmail.com"
app.config["MAIL_PORT"] = 465
app.config["MAIL_USE_SSL"] = True
app.config["MAIL_USERNAME"] = 'removed'
app.config["MAIL_PASSWORD"] = 'removed'
mail.init_app(app)
解决问题的正确代码:
from flask import Flask
app = Flask(__name__)
app.secret_key = 'development key'
app.config["MAIL_SERVER"] = "smtp.gmail.com"
app.config["MAIL_PORT"] = 465
app.config["MAIL_USE_SSL"] = True
app.config["MAIL_USERNAME"] = 'removed'
app.config["MAIL_PASSWORD"] = 'removed'
from routes import mail
mail.init_app(app)
import user.routes