我用 Flask 和 Python 构建了一个简单的 Web 应用程序,我打算将其上传到 Heroku。
在本地启动我的应用程序时,使用以下脚本:
#!venv/bin/python
from app import app
app.run(debug = True)
我收到此错误消息:
Traceback (most recent call last):
File "./run.py", line 2, in <module>
from app import app, mail
File "/home/ricardo/personalSite/app/__init__.py", line 3, in <module>
from app import index
File "/home/ricardo/personalSite/app/index.py", line 6, in <module>
from emails import send_email
File "/home/ricardo/personalSite/app/emails.py", line 2, in <module>
from app import app, mail
ImportError: cannot import name mail
因此,它无法导入
mail
。在
app
目录中,我有这个 __init__.py
,这是我创建的 Mail
对象,这让我无法导入:from flask import Flask
app = Flask(__name__)
from app import index
from flask.ext.mail import Mail
mail = Mail(app)
这是我调用
emails.py
函数的文件 send_mail
:from flask.ext.mail import Message
from app import app, mail
from flask import render_template
from config import ADMINS
from decorators import async
因此,根据错误消息,错误在此文件中,位于
from app import app, mail
中。问题是什么?为什么不能导入
mail
?更新:
这是我的目录列表:
persSite\
venv\
<virtual environment files>
app\
static\
templates\
__init__.py
index.py
emails.py
decorators.oy
tmp\
run.py
最佳答案
你有一个循环依赖。您必须了解 Python 在导入文件时在做什么。
每当 Python 导入文件时,Python 都会查看该文件之前是否已经开始导入。因此,如果模块 A 导入了模块 B,而模块 B 又导入了模块 A,那么 Python 将执行以下操作:
这是
app/__init__.py
,这是要导入的第一个文件。from flask import Flask
app = Flask(__name__)
from app import index # <-- See note below.
from flask.ext.mail import Mail
mail = Mail(app)
当这个文件被导入时,它只是运行脚本的 Python。创建的任何全局属性都成为模块属性的一部分。因此,当您点击第三行时,属性 'Flask' 和 'app' 已经定义。但是,当您点击第三行时,Python 开始尝试从
index
导入 app
。因此,它开始运行 app/index.py
文件。当然,这看起来像下面这样:
from flask.ext.mail import Message
from app import app, mail # <-- Error here
from flask import render_template
from config import ADMINS
from decorators import async
请记住,当这个 Python 文件被导入时,到目前为止你只在
Flask
模块中定义了 app
和 app
。因此,尝试导入 mail
是行不通的。因此,您需要重新排列代码,以便如果
app.index
依赖于 app
中的属性,则 app
在尝试导入之前定义该属性 0x25181223134314关于python - "ImportError: cannot import name mail"在 flask 中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19466045/