试图使用相对导入,打破了我的导入路径?

时间:2013-06-30 14:20:10

标签: python flask importerror

我在Mac上本地运行Flask服务器。

我的项目:

project/my_lib/my_class.py  
project/testing/flask_server.py  
project/testing/something/test_class.py  

有一次,我尝试使用一些相对导入来测试不同目录中的类:

project / testing / something / test_class.py中:

from ..my_lib.my_class import MyClass

这给了我一个错误:

ValueError: Attempted relative import beyond toplevel package

所以我退出了,但现在我无法让我的Flask服务器运行,即使我删除了新的导入代码。

$ python testing/flask_server.py

吐出这个:

Traceback (most recent call last):
  File "testing/flask_server.py", line 2, in <module>
    from flask import Flask
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/__init__.py", line 17, in <module>
    from werkzeug.exceptions import abort
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/werkzeug/__init__.py", line 154, in <module>
    __import__('werkzeug.exceptions')
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/werkzeug/exceptions.py", line 71, in <module>
    from werkzeug.wrappers import Response
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/werkzeug/wrappers.py", line 26, in <module>
    from werkzeug.http import HTTP_STATUS_CODES, \
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/werkzeug/http.py", line 28, in <module>
    from urllib.request import parse_http_list as _parse_list_header
ImportError: No module named request

咦?


更新

烧瓶导入错误仅发生在最初调用错误代码的目录中。也就是说,如果我这样做

from flask import Flask

来自项目/测试目录中的任何地方,我收到导入错误,但如果我在项目/ 或我系统上的任何其他位置执行此操作,那就没关系了。 ?


解决方案(部分):

我没有解释为什么会发生这种情况,但我做了以下修复:

  1. 创建了一个新的 testing / 目录,并将旧文件中的文件复制到其中。必须删除旧的 testing / 目录 - 它基本上已损坏。
  2. 我的跨目录导入是使用绝对路径而不是相对路径。
  3. (顺便说一句,我试图回溯我的步骤来重现相对导入错误但是无法做到,所以我不确定这一切的原因或解决方案。)

1 个答案:

答案 0 :(得分:2)

您的系统路径中可能有自己的urllib2 python文件,可能位于本地目录中。不要这样做,因为它会中断werkzeug(和其他python代码)。

为了与python 2和3兼容,werkzeug使用如下构造:

try:
    from urllib2 import parse_http_list as _parse_list_header
except ImportError: # pragma: no cover
    from urllib.request import parse_http_list as _parse_list_header

如果您有一个掩盖标准库文件的本地from urllib2 import parse_http_list as _parse_list_header模块或ImportError包,则urllib2.py行可能会抛出urllib2/__init__.py异常。

因为第一次导入会抛出ImportError,所以执行第二行,失败,因为urllib.request包仅在Python 3上可用。

从您的项目中,运行以下代码以诊断您拥有该模块的

import urllib2
print urllib2.__file__

如果仍然有效,请运行:

from urllib2 import parse_http_list as _parse_list_header

因为urllib2可能会间接导入你屏蔽的内容。例如,urllib2使用from urlib import ...语句,因此本地urllib模块也会破坏导入。

from flask import Flask行之前,从烧瓶项目执行非常重要。