在嵌套包中导入模块
Posted
技术标签:
【中文标题】在嵌套包中导入模块【英文标题】:importing a module in nested packages 【发布时间】:2011-01-12 02:19:13 【问题描述】:这是一个python新手问题:
我的目录结构如下:
test
-- test_file.py
a
-- b
-- module.py
其中test
、a
和b
是文件夹。 test
和 a
处于同一级别。
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所述:
请注意,显式和隐式相对导入都基于当前模块的名称。由于主模块的名称始终为“main”,因此用作 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
文件。这意味着您将在a
和b
目录中拥有这样的文件。然后你可以直接做一个
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
。详情请查看答案中的链接。以上是关于在嵌套包中导入模块的主要内容,如果未能解决你的问题,请参考以下文章
如何从包内的两个不同文件夹中导入一个模块,该模块导入另一个模块
在 Angular 中导入全局 css 文件会导致 Webpack 发出巨大的模块包