【问题标题】:Tried to use relative imports, and broke my import paths?尝试使用相对导入,并破坏了我的导入路径?
【发布时间】:2013-06-30 14:20:10
【问题描述】:

我在我的 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

project/testing 目录中的任何位置,我都会收到导入错误,但如果我在 project/ 或系统上的任何其他位置执行此操作,那就没问题了。 .?


解决方案(部分):

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

  1. 创建了一个新的 testing/ 目录并将旧目录中的文件复制到其中。必须删除旧的 testing/ 目录 - 它基本上已损坏。
  2. 我的跨目录导入是否使用绝对路径而不是相对路径。

(顺便说一句,我试图追溯我的步骤以重现相关导入错误但无法重现,所以我不确定整个事情的原因或解决方案。)

【问题讨论】:

    标签: python flask importerror


    【解决方案1】:

    您的系统路径中可能有自己的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
    

    如果您有一个本地 urllib2.py 模块或 urllib2/__init__.py 包来屏蔽标准库文件,from urllib2 import parse_http_list as _parse_list_header 行可能会引发 ImportError 异常。

    因为第一次导入抛出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 行之前。

    【讨论】:

    • 谢谢-这就是print urllib2.__file__ yeilds:/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/urllib2.pyc。它不是本地的,我正在运行与导致导入错误之前相同的代码。所以我仍然不清楚为什么我以前工作的代码现在被破坏了,以及如何修复它。
    • 接下来试试from urllib2 import ...
    • from urllib2 import ... 行没有错误(那么为什么from urllib.request import... 行甚至被调用?!)
    • 非常感谢您为此付出的努力。不幸的是,在我删除目录并重新开始之后(如上所述),我什至无法重现错误,因此我们对此没有明确的答案。不过,我会给你荣誉,因为它仍然是一个很好的答案。
    猜你喜欢
    • 1970-01-01
    • 2015-12-07
    • 2015-01-07
    • 2015-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多