繁体   English   中英

Python 模块的绝对与显式相对导入

[英]Absolute vs. explicit relative import of Python module

我想知道在 Python 应用程序中导入包的首选方法。 我有这样的包结构:

project.app1.models
project.app1.views
project.app2.models

project.app1.views导入project.app1.modelsproject.app2.models 我想到了两种方法来做到这一点。

绝对进口:

import A.A
import A.B.B

或者使用显式相对导入,如Python 2.5 和 PEP 328中引入的那样:

# explicit relative
from .. import A
from . import B

最pythonic的方法是什么?

不再强烈反对 Python 相对导入,但在这种情况下强烈建议使用 absolute_import。

请参阅引用 Guido 本人的讨论

“这主要不是历史吗?在实施新的相对导入语法之前,相对导入存在各种问题。短期解决方案是建议不要使用它们。长期解决方案是实施明确的语法。现在现在是撤回反推荐的时候了。当然,不过分——我仍然发现它们是一种后天习得的品味;但它们有自己的位置。”

OP 正确链接了PEP 328 ,它说:

介绍了几个用例,其中最重要的是能够重新排列大型包的结构而无需编辑子包。 此外,如果没有相对导入,包内的模块无法轻松导入自身。

另请参阅几乎重复的问题When or why to use relative imports in Python

当然,这仍然是一个品味问题。 虽然使用相对导入更容易移动代码,但这也可能出乎意料地破坏事情; 重命名导入并不困难。

要强制使用 PEP 328 的新行为,请使用:

from __future__ import absolute_import

在这种情况下,隐式相对导入将不再可能(例如import localfile将不再起作用,只能from. import localfile )。 对于干净和面向未来的行为,建议使用 absolute_import 。

一个重要的警告是,由于PEP 338PEP 366 ,相对导入需要将 python 文件作为模块导入 - 你不能执行具有相对导入的 file.py 否则你会得到一个ValueError: Attempted relative import in non-package

在评估最佳方法时应考虑到这一限制。 Guido 反对在任何情况下从模块运行脚本:

我对此以及 __main__ 机器的任何其他提议的摆弄都是-1。 唯一的用例似乎是运行恰好位于模块目录中的脚本,我一直将其视为反模式。 要让我改变主意,你必须说服我事实并非如此。

关于这个问题的详尽讨论可以在 SO 上找到; 回覆。 Python 3 这是相当全面的:

绝对进口。 来自 PEP 8:

强烈建议不要使用包内导入的相对导入。 始终对所有导入使用绝对包路径。 即使现在 PEP 328 [7] 已在 Python 2.5 中完全实现,其显式相对导入的风格仍被积极劝阻; 绝对导入更便携,通常更易读。

显式相对导入是一个很好的语言特性(我猜),但它们远不如绝对导入那么显式。 更具可读性的形式是:

import A.A
import A.B.B

特别是如果您导入多个不同的命名空间。 如果你看一些写得很好的项目/教程,其中包括从包中导入,它们通常遵循这种风格。

为使其他人(也许还有您)在将来试图弄清楚您的名称空间(尤其是如果您迁移到 3.x,其中一些包名称已更改)。

相对导入不仅让你以后可以自由地重命名你的包,而无需更改几十个内部导入,而且我还成功地解决了涉及循环导入或命名空间包等问题的某些问题,因为它们不会将 Python“送回” top" 从顶级命名空间重新开始搜索下一个模块。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM