【问题标题】:Force importing module from current directory强制从当前目录导入模块
【发布时间】:2012-12-22 09:03:48
【问题描述】:

我有包p,其中有模块aba 依赖于b

b.py 内容:

import a

但是我想确保b 从同一个p 包目录导入我的a 模块,而不是从PYTHONPATH 导入任何a 模块。

所以我尝试将b.py 更改如下:

from . import a

只要我在p 包目录之外时导入b,它就可以工作。给定以下文件:

/tmp
    /p
       a.py
       b.py
       __init__.py

以下作品:

$ cd /tmp
$ echo 'import p.b' | python

以下操作无效:

$ cd /tmp/p
$ echo 'import b' | python
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "b.py", line 1, in <module>
    from . import a
ValueError: Attempted relative import in non-package

为什么?

附:我正在使用 Python 2.7.3

【问题讨论】:

    标签: python


    【解决方案1】:

    因为/p 中有一个__init__.py 文件。该文件告诉 Python:“此文件夹中的所有模块都在包 p 中”。

    只要__init__.py文件存在,无论你身在何处,都可以将b导入为p.b

    所以b.py 中的正确导入应该是:import p.a

    【讨论】:

    • 哪个版本的 Python?这种行为在过去发生了变化。
    • 按照您的建议更改b.py。现在运行import b 产生ImportError: No module named p.a。 Python 2.7.3
    • 你不应该在这种情况下使用import b。始终使用import p.b 或从__init__.pyimport p 提供必要的符号来隐藏内部细节。
    • 您的问题是您正在混合(旧)相对导入和新的基于包的导入。旧的进口是善变的,这就是引入新风格进口的原因。请参阅docs.python.org/2/tutorial/modules.html#packages中的“包”
    • 那么完成我的任务的正确方法是什么? import p.ab.py?它可以工作,但如果我想将 p 重命名为其他名称,我将不得不更改很多文件......
    【解决方案2】:

    相对导入仅适用于包内。

    如果你从你所在的地方导入b,则没有包的概念,因此无法进行相对导入。

    如果你导入p.b,它就是包c中的模块b

    重要的不是目录结构,而是包结构。

    【讨论】:

      【解决方案3】:

      重读Pythonimport documentation后,我原来的问题正确答案是:

      为了确保b 从自己的包中导入a,只需在b 中编写以下内容即可:

      import a
      

      这是来自文档的引用:

      子模块经常需要相互引用。例如, 环绕模块可能使用回声模块。事实上,这样的引用 是如此常见,以至于 import 语句首先在包含 在查看标准模块搜索路径之前打包。

      注意:正如 J.F. Sebastian 在下面的评论中所建议的,不建议使用隐式导入,事实上,它们在 Python 3 中已经消失了。

      【讨论】:

      • 不要使用隐式相对导入(它们在 Python 3 中消失了)。始终使用绝对导入(from p import a(如果有 p/p.py 文件,则在其前面添加 from __future__ import absolute_import)或显式相对导入(from . import a(如果它不是 __main__ 模块))。不要从 Python 包目录中运行脚本;它将这个目录添加到 sys.path 之前,这可能会导致相同的模块以不同的名称可用,从而导致与模块级状态相关的错误(如果您使用隐式相对导入;在这种情况下,它也会影响其他顶级模块)。
      猜你喜欢
      • 1970-01-01
      • 2021-01-14
      • 2020-11-03
      • 1970-01-01
      • 2015-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多