在嵌套包中导入模块

Posted

技术标签:

【中文标题】在嵌套包中导入模块【英文标题】:importing a module in nested packages 【发布时间】:2011-01-12 02:19:13 【问题描述】:

这是一个python新手问题:

我的目录结构如下:

test
 -- test_file.py
a
 -- b
   -- module.py    

其中testab 是文件夹。 testa 处于同一级别。

module.py 有一个名为shape 的类,我想在 test_file.py 中实例化它的一个实例。我该怎么做?

我试过了:

from a.b import module

但我得到了:

ImportError: No module named a.b

【问题讨论】:

见***.com/questions/72852/…。 【参考方案1】:

你想要的是一个相对导入,比如:

from ..a.b import module

这个问题是如果你调用 test_file.py 作为你的主模块,它就不起作用。如here所述:

请注意,显式和隐式相对导入都基于当前模块的名称。由于主模块的名称始终为“ma​​in”,因此用作 Python 应用程序主模块的模块应始终使用绝对导入。

所以,如果你想调用 test_file.py 作为你的主模块,那么你应该考虑改变你的模块的结构并使用绝对导入,否则只使用上面的相对导入。

【讨论】:

致(我不知道的)投反对票的人:当你对一个答案投反对票时,你应该留下评论来解释它有什么问题,这样任何阅读它的人(和作者)都可以被告知关于错误... 我收到 ValueError: Attempted relative import in non-package 您显然正在运行 test_file 作为您的主模块。在这种情况下,您需要将调用者模块移动到顶层或设置 PYTHOPATH 以包含您尝试导入的包(另请参阅下面 S.Lott 的回答)。【参考方案2】:

    目录a 需要是一个包。添加一个__init__.py 文件使其成为一个包,这比一个简单的目录更上一层楼。

    目录b也需要是a的子包。添加一个__init__.py 文件。

    目录test 也应该是一个包。很难说这是否有必要。通常最好将 Python 模块的每个目录都作为一个正式的包。

    为了import,包需要在sys.path;这是从PYTHONPATH 环境变量构建的。默认情况下,安装的站点包和当前工作目录(实际上)是唯一可以找到包的两个地方。

    这意味着必须安装a,或者,您当前的工作目录也必须是a 上一级的包。

    或者,您需要将PYTHONPATH 环境变量设置为包含a

http://docs.python.org/tutorial/modules.html#the-module-search-path

http://docs.python.org/using/cmdline.html#envvar-PYTHONPATH

另外,http://docs.python.org/library/site.html 了解有关如何构建 sys.path 的完整信息。

【讨论】:

【参考方案3】:

首先要做的是快速浏览the official docs on this。

要将目录变成一个包,您必须添加一个__init__.py 文件。这意味着您将在ab 目录中拥有这样的文件。然后你可以直接做一个

import a.b.module

但是您必须将其称为a.b.module,这很乏味,因此您可以像这样使用导入的as 形式

import a.b.module as mod #shorter name

并将其称为mod

然后你可以使用像mod.shape() 这样的常规约定来实例化mod 中的东西。

还有一些其他的微妙之处。请通过文档了解详细信息。

【讨论】:

我确实将 a.b.module 作为 mod 导入并为所有包添加了 init.py 但我收到 ImportError: No module named a.b.module @khell 您应该从根目录运行命令,例如 python test/test_file.py 它是__init__.py。不是init.py。详情请查看答案中的链接。

以上是关于在嵌套包中导入模块的主要内容,如果未能解决你的问题,请参考以下文章

python 中导入redis模块

如何从包内的两个不同文件夹中导入一个模块,该模块导入另一个模块

在 Angular 中导入全局 css 文件会导致 Webpack 发出巨大的模块包

在 Python 中导入深度嵌套的模块

无法在 Python 中导入位置设置为 PYTHONPATH 的模块

我无法使用 PythonKit 在 Xcode 11 中导入 Python 模块