包内模块的相对导入

Relative import of a module within a package

如何使包内模块 .adipiscing.lorem_ipsum 可用,完全使用导入系统 没有'不使用无关的名称?

给定一个代码库:

foo/
    consecteur.py
    adipiscing/
        lorem_ipsum.py

consecteur模块需要访问adipiscing.lorem_ipsum模块。

这就是我想要做的:

# consecteur.py

from . import adipiscing.lorem_ipsum

dolor = adipiscing.lorem_ipsum.dolor_sit_amet()

那不行; from . import adipiscing.lorem_ipsum 是语法错误。

不满足的选项

使用隐式相对导入

# consecteur.py

import adipiscing.lorem_ipsum

dolor = adipiscing.lorem_ipsum.dolor_sit_amet()

这不必要地混淆了 adipiscing.lorem_ipsum 是绝对导入还是相对导入。当导入是相对的时,代码应该是显式的。

将模块从其命名空间包中拉出

# consecteur.py

from .adipiscing import lorem_ipsum

dolor = lorem_ipsum.dolor_sit_amet()

这会丢失通过阅读 adipiscing.lorem_ipsum 传达的有价值的信息,特别是如果 lorem_ipsum 是一个通用词 需要 adipiscing 包命名空间。

使用损坏的名称导入

# consecteur.py

from .adipiscing import lorem_ipsum as adipiscing_lorem_ipsum

dolor = adipiscing_lorem_ipsum.dolor_sit_amet()

这在视觉上令人困惑;期待 adipiscing.lorem_ipsum 的人可以很容易地输入期望它有效的内容,但该名称不可用。制作一个容易混淆的相似名称并不是一个好的解决方案;也不是创建一个独特的名称,因为整个目的是使 adipiscing.lorem_ipsum 可用。

如果包名或模块名中的一个或两个实际上已经有下划线,这也是不明确的。如果下划线代表一个点,则它与实际包含下划线的名称无法区分。

导入包,尝试使用模块

# consecteur.py

from . import adipiscing

dolor = adipiscing.lorem_ipsum.dolor_sit_amet()

这是一个 AttributeError,因为 adipiscing.lorem_ipsum 现在不可用;仅通过导入包含包的模块不会自动可用。

导入包,然后导入模块但不要使用它的名字

# consecteur.py

from . import adipiscing
from .adipiscing import lorem_ipsum

dolor = adipiscing.lorem_ipsum.dolor_sit_amet()

这个 hack 成功了,但是导入语句 from .adipiscing import lorem_ipsum 声明我们将使用裸 lorem_ipsum 名称。

因为这不是真的,静态代码检查器将(正确地)抱怨未使用的导入。我同意那些代码检查器,所以我不想只是让警告静音;我想避免黑客入侵,但仍然可以使用 adipiscing.lorem_ipsum 名称。

那么,如何使用 显式相对导入 使 adipiscing.lorem_ipsum 名称可用于代码 通过该名称 ], 没有未使用的导入?

目前似乎无法使用 Python 导入系统执行此操作。

Python 的解释器不支持您想要的语法。但是您可以使用 as 作为 "Pull the module out of its namespace package" 的解决方法。例如:

from .lorem import ipsum as lorem_ipsum

dolor = lorem_ipsum.dolor_sit_amet()

这样做你会得到完整的上下文 lorem's ipsum