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

发布于 2024-10-02 20:37:06 字数 597 浏览 2 评论 0原文

我想知道在 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

或使用显式相对导入,如 带有 PEP 328 的 Python 2.5

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

执行此操作最 Pythonic 的方法是什么?

I'm wondering about the preferred way to import packages in a Python application. I have a package structure like this:

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

project.app1.views imports project.app1.models and project.app2.models. There are two ways to do this that come to mind.

With absolute imports:

import A.A
import A.B.B

or with explicit relative imports, as introduced in Python 2.5 with PEP 328:

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

What is the most pythonic way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

闻呓 2024-10-09 20:37:06

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

请参阅引用 Guido 本人的此讨论

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

OP 正确链接了 PEP 328 说:

提出了几个用例,其中最重要的是
能够重新排列大型包的结构,而无需
编辑子包。另外,包内的模块不能轻易地
导入自身而不进行相对导入。

另请参阅几乎重复的问题 何时或为何在 Python 中使用相对导入

当然,这仍然是一个品味问题。虽然通过相对导入来移动代码更容易,但这也可能会意外地破坏事情;重命名导入并不那么困难。

要强制 PEP 328 使用新行为:

from __future__ import absolute_import

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

一个重要的警告是,由于 PEP 338PEP 366,相对导入要求将 python 文件作为模块导入 - 您无法执行这样的 file.py具有相对导入,否则您将收到 ValueError: Attemptedrelative import in non-package

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

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

关于此事的详尽讨论可以在 SO 上找到;关于。 Python 3 这是相当全面的:

Python relative imports are no longer strongly discouraged, but using absolute_import is strongly suggested in that case.

Please see this discussion citing Guido himself:

"Isn't this mostly historical? Until the new relative-import syntax
was implemented there were various problems with relative imports. The
short-term solution was to recommend not using them. The long-term
solution was to implement an unambiguous syntax. Now it is time to
withdraw the anti-recommendation. Of course, without going overboard
-- I still find them an acquired taste; but they have their place."

The OP correctly links the PEP 328 that says:

Several use cases were presented, the most important of which is being
able to rearrange the structure of large packages without having to
edit sub-packages. In addition, a module inside a package can't easily
import itself without relative imports.

Also see almost duplicate question When or why to use relative imports in Python

Of course it still stands as a matter of taste. While it's easier to move code around with relative imports, that might also unexpectedly break things; and renaming the imports is not that difficult.

To force the new behaviour from PEP 328 use:

from __future__ import absolute_import

In this case, implicit relative import will no longer be possible (eg. import localfile will not work anymore, only from . import localfile). For clean and future proof behaviour, using absolute_import is advisable.

An important caveat is that because of PEP 338 and PEP 366, relative imports require the python file to be imported as a module - you cannot execute a file.py that has a relative import or you'll get a ValueError: Attempted relative import in non-package.

This limitation should be taken into account when evaluating the best approach. Guido is against running scripts from a module in any case:

I'm -1 on this and on any other proposed twiddlings of the __main__ machinery.
The only use case seems to be running scripts that happen to be living inside a module's directory, which I've always seen as an antipattern.
To make me change my mind you'd have to convince me that it isn't.

Exhaustive discussions on the matter can be found on SO; re. Python 3 this is quite comprehensive:

多彩岁月 2024-10-09 20:37:06

绝对进口。来自 PEP 8:

包内导入的相对导入量非常高
灰心。
始终对所有导入使用绝对包路径。
即使现在 PEP 328 [7] 已在 Python 2.5 中完全实现,
其明确的相对进口风格受到积极劝阻;
绝对导入更便携,通常也更易读。

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

import A.A
import A.B.B

特别是当您导入多个不同的名称空间时。如果您查看一些编写良好的项目/教程,其中包含从包内导入的内容,它们通常遵循这种风格。

当其他人(也许还有你)试图找出你的命名空间时(特别是如果你迁移到 3.x,其中某些包名称已更改)。

Absolute imports. From PEP 8:

Relative imports for intra-package imports are highly
discouraged.
Always use the absolute package path for all imports.
Even now that PEP 328 [7] is fully implemented in Python 2.5,
its style of explicit relative imports is actively discouraged;
absolute imports are more portable and usually more readable.

Explicit relative imports are a nice language feature (I guess), but they're not nearly as explicit as absolute imports. The more readable form is:

import A.A
import A.B.B

especially if you import several different namespaces. If you look at some well written projects/tutorials that include imports from within packages, they usually follow this style.

The few extra keystrokes you take to be more explicit will save others (and perhaps you) plenty of time in the future when they're trying to figure out your namespace (especially if you migrate to 3.x, in which some of the package names have changed).

舟遥客 2024-10-09 20:37:06

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

Relative imports not only leave you free to rename your package later without changing dozens of internal imports, but I have also had success with them in solving certain problems involving things like circular imports or namespace packages, because they do not send Python "back to the top" to start the search for the next module all over again from the top-level namespace.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文