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

时间:2010-11-17 22:07:10

标签: python package python-import

我想知道在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 with PEP 328中所述:

# explicit relative
import ..A
import .B

最狡猾的方式是什么?

3 个答案:

答案 0 :(得分:107)

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

请参阅this discussion引用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这是非常全面的:

答案 1 :(得分:41)

绝对进口。从PEP 8开始:

  

包装内进口的相对进口量很高   泄气。         始终对所有导入使用绝对包路径。         即使现在PEP 328 [7]完全在Python 2.5中实现,         其积极的相对进口风格受到积极劝阻;         绝对导入更具可移植性,通常更具可读性。

明确的相对导入是一个很好的语言功能(我猜),但它们并不像绝对导入那样明确。更易读的形式是:

import A.A
import A.B.B

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

你想要更明确的几次额外击键将会在他们试图找出你的命名空间时为其他人(也许是你)节省大量时间(特别是如果你迁移到3.x,其中一些包名称已更改)。

答案 2 :(得分:30)

相对导入不仅让您可以在不更改数十个内部导入的情况下随意重命名您的包,但我也成功地解决了涉及循环导入或命名空间包等问题的某些问题,因为他们不发送Python“回到顶端“从顶级命名空间开始重新搜索下一个模块。