【问题标题】:"ImportError: cannot import name mail" in FlaskFlask 中的“ImportError:无法导入名称邮件”
【发布时间】:2013-10-19 12:31:33
【问题描述】:

我用 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)

这是我调用send_mail函数的文件emails.py

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 flask


    【解决方案1】:

    你有一个循环依赖。你必须意识到 Python 在导入文件时在做什么。

    每当 Python 导入文件时,Python 都会查看该文件之前是否已经开始导入。因此,如果模块 A 导入模块 B,模块 B 导入模块 A,那么 Python 将执行以下操作:

    • 开始运行模块 A。
    • 当模块 A 尝试导入模块 B 时,暂时停止运行模块 A,并开始运行模块 B。
    • 当模块 B 尝试导入模块 A 时,Python 将不会继续运行模块 A 直到完成;相反,模块 B 将只能从模块 A 导入在模块 B 开始运行之前已经定义的属性。

    这里是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 开始尝试从app 导入index。因此,它开始运行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 文件被导入时,到目前为止,您只在 app 模块中定义了 Flaskapp。因此,尝试导入mail 将不起作用。

    因此,您需要重新排列您的代码,以便如果 app.index 依赖于 app 中的属性,则 app 在尝试导入 app.index 之前定义该属性。

    【讨论】:

    • 感谢您的详尽回答 Mark Hildreth。我明白你在说什么,但我似乎还不能正确地重新排列我的代码。我会继续努力的。
    • 好的。我现在明白了。再次感谢您。我从未想过 Python 中的导入是如何工作的。
    • @Xar:你能分享一下你是怎么解决的吗?
    • 这是我迄今为止读过的最简洁的进口解释!
    • 我希望我能用 10000K 赞来祝福这篇文章。
    【解决方案2】:

    这可能是问题所在:

    from app import app, mail
    

    在“app/emails.py”文件中,导入来自当前模块,而不是嵌套的应用模块。试试:

    from . import app, mail
    

    如果它不起作用,您应该使用更详细的目录列表更新您的问题。

    【讨论】:

    • 我按照建议更改了代码,但它仍然给我同样的错误。正如你所说,我会用我的目录列表更新我的问题。
    猜你喜欢
    • 2018-08-10
    • 2019-05-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 2019-06-03
    • 2021-06-28
    • 2014-12-19
    相关资源
    最近更新 更多