更新:
该错误(在这种情况下)不是由循环导入引起的,而是由virtualenv
配置中的缺陷引起的。有关详细说明,请参见下面的my answer。
我正在使用:
我正在使用Flask构建Web应用程序,除其他外,我还需要能够向用户发送邮件的功能。我建立了一个单独的Python模块,该模块将负责邮件处理。在我将电子邮件处理模块添加到应用程序后,尽管遇到了一个奇怪的(至少在我看来,至少是)import
问题。
这是我遇到的(绝缘)import
问题:
app.py
from flask import Flask
from test_mail import EmailTool
app = Flask(__name__)
@app.route('/')
def index():
return 'Testing!'
test_mail.py
from email.message import EmailMessage
class EmailTool(object):
pass
启动我的应用并建立索引(即/
)后,我收到:
Traceback (most recent call last):
File "/app.py", line 2, in <module>
from tmp_test_mail import EmailTool
File "/test_mail.py", line 1, in <module>
from email.message import EmailMessage
ImportError: cannot import name EmailMessage
我已更改 test_mail.py 的代码,以确保可以访问email
模块:
import email
class EmailTool(object):
pass
这样我就不会出错。
寻找可能的原因和解决方案使我相信(1,2,3,4,5),这很可能与事情有关与循环参考。尽管即使通读了所有上述材料并找出了问题的根源,但我仍然看不到它如何成为圆形参考。因此,我得出结论,这要么不是循环的,而是其他原因造成的,要么是循环的,而我在这里遗漏了一些明显的东西。
我正在寻求帮助以了解以下内容:
from email.message import EmailMessage
时会出错,但是如果我做import email
却不出错?答案 0 :(得分:1)
要回答两个问题:
第一
否,在上方提供的代码不应该是循环的,除非email.message
包含对app
模块的引用,并假设app
是有效的模块。
第二
从email
而不是email.message
导入不会导致任何错误,因为您不是在导入(看似)有问题的EmailMessage
类,因为它位于email.message
中,而不是email
。我的理论是,这是由于某些导入循环返回到位于app
模块中的email.message
模块中引起的。
在撰写本文时,我还不知道email
或email.message
是标准(3.6.x)库的一部分,因为我从未使用过与这些模块相关的任何东西(而我没有我不常使用python 3.x <),因此我认为这是由作者建议的循环引用引起的。事实证明(并在original post中指出),这是由something else entirely引起的。
答案 1 :(得分:0)
TL; DR :实际的问题与循环依赖无关-事实证明是我的虚拟环境配置错误( Python版本实际上是2.7.10 ,如hjpotter92的评论所建议)。
我是如何找到原因的(作为调试Python venv
的食谱集发布,以后可能对我自己以及希望其他人都方便):
在阅读了我的问题的注释(特别是hjpotter92的注释)之后,我急着检查了virtualenv
中我从(即使我在发布问题之前已经检查过它-在这种事情上也不能太小心=)。
(在虚拟环境中)运行:
python --version
给我(正如我所期望的那样):
Python 3.6.1
虽然=),但我还是不服气。如以下答案所建议:1和2,我已经在两个模块中添加了以下代码:app.py
和test_mail.py
(以便检查哪个版本的Python,它们实际上是通过运行的):
import sys
...
print(sys.version)
它正在输出(对我来说令人惊讶):
2.7.10
好的,显然这里有些问题。我已决定重新了解关于virtualenv
设置的基本知识。我偶然发现的first article建议pip --version
作为设置过程的第二步(在python --version
之后)。我没有什么要放松的(当然是在虚拟环境中)运行的,(令我惊讶的是)它给了我:
pip 9.0.1 from /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages (python 2.7)
因此,以某种方式在虚拟环境中使用的pip
是系统级别的一个...
在这一点上,我怀疑我的应用程序是完全从virtualenv
运行的。按照this answer的食谱(对其进行和评论),我编写并添加了以下代码段,并将其添加到app.py
和test_mail.py
中:
import sys
...
if hasattr(sys, 'real_prefix'):
print('Python 2 venv')
elif (hasattr(sys, 'base_prefix') and sys.prefix != sys.base_prefix):
print('Python 3 venv')
else:
print('Not venv!')
正在打印Not venv!
并不奇怪(目前)。
Flask
和相关软件包(itsdangerous
,Jinja2
,MarkupSafe
,Werkzeug
)(出于某种原因安装在此处)通过pip uninstall <package_name>
。python3 -m venv <env_name>
重新创建虚拟环境现在,回答我自己的问题:
from email.message import EmailMessage
后发生错误,是因为实际上使用了python 2.7.10,如果我们研究此版本的Python的source code of message.py
,我们会发现它确实可以不包含名为EmailMessage
的类。 source code of message.py
for Python 3.6.* library确实包含名为EmailMessage
的类。