如何在子包装内进行绝对进口?

时间:2014-07-28 17:26:17

标签: python python-2.7

有些东西让我对包装中的进口感到烦恼。 想象一下,我有以下目录结构:

pack
├── __init__.py
├── sub1
│   ├── __init__.py
│   └── mod1.py
└── sub2
    ├── __init__.py
    └── mod2.py

在mod1.py中我有以下代码来导入mod2.py:

# mod1.py
import pack.sub2.mod2
pack.sub2.mod2.helloworld()

我在包含导入pack / sub1 / mod1.py

的包的目录中有一个main.py文件

mod1.py如何访问pack? pack与mod1.py不在同一目录中。 python是否自动将最顶层的包添加到sys.path?

1 个答案:

答案 0 :(得分:3)

您可以通过检查交互式解释器中的sys.path来对此进行调查。你会发现它的第一个元素是解释器被告知要运行的脚本的位置。这意味着当您在顶级(pack包的位置)运行脚本时,该位置会自动添加到sys.path。它与实际的包结构没有任何关系,所以如果你把mod1.py作为一个脚本运行就会让事情破裂(这可能就是你将脚本放在顶层的原因!)。

请注意,在Python 2中,您还存在隐式相对导入的问题,这不会影响您所询问的问题,但如果您涉及更多模块,则可能会出现问题。如果您将mod3.py添加到sub1,则可以仅使用mod1import mod3导入,并隐式计算pack.sub1前缀。这种隐式行为通常被认为是一件坏事,并且在Python 3中不允许这样的隐式相对导入(您也可以使用from __future__ import absolute_import在Python 2中禁用它们)。要从pack.sub1.mod3导入pack.sub1.mod1,您需要完整命名,或使用显式相对导入:from . import mod3

要将此相对导入业务与您的问题联系起来,如果您希望避免依赖pack成为sys.path的一部分(或者更现实地,防止对pack的更改名称),您可以将mod2的导入从mod1修改为显式相对导入。只需使用from .. import sub2.mod2