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

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

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

project.app1.views导入project.app1.modelsproject.app2.models 。 想到这个,有两种方法可以做到这一点。

绝对import:

 import AA import ABB 

或者使用Python 2.5和PEP 328引入的显式相对导入:

 # explicit relative import ..A import .B 

什么是最pythonic这样做呢?

绝对import。 从PEP 8:

封装内import的相对import非常令人沮丧。 始终使用所有导入的绝对包path。 即使现在PEP 328 [7]已经在Python 2.5中完全实现,其显式相对导入的风格也被阻止了。 绝对导入更便携,通常更具可读性。

显式相对导入是一个很好的语言function(我猜),但它们不像绝对导入那么明确。 更可读的forms是:

 import AA import ABB 

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

如果你想要更明确一些额外的按键,那么当他们试图找出你的名字空间时(尤其是如果你迁移到3.x,其中一些包名字已经改变)。

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

请参阅Guido本人的讨论 :

“这不是大多数的历史吗?直到新的相对导入语法被实现之后,相对导入才出现了各种各样的问题,短期的解决scheme是不推荐使用它们,长期的解决scheme是实现一个明确的语法。现在是撤销反推荐的时候了,当然,不要过度的 – 我仍然觉得它们是一种后天的味道,但是它们有它们的位置。

OP正确地链接了PEP 328 ,它表示:

介绍了几个用例,其中最重要的是能够重新排列大包的结构而不必编辑子包。 另外,一个包内的模块在不进行相对导入的情况下不能轻易导入。

也看到几乎重复的问题什么时候或为什么要在Python中使用相对导入

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

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

 from __future__ import absolute_import 

在这种情况下,隐含的相对导入将不再可能(例如import localfile不再可用,只能from . import localfile )。 为了干净和将来的certificate行为,build议使用absolute_import。

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

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

我对这个以及其他主要机器的提议都是-1。 唯一的用例似乎是运行在模块目录中的脚本,我一直认为这是一个反模式。 为了让我改变主意,你必须说服我,它不是。

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

  • Python 3中的相对导入

相对导入不仅可以让您自由地重命名您的软件包,而不需要改变几十个内部导入,但是我也在解决某些涉及循环导入或名称空间包等问题方面取得了成功,因为它们不会将Python“发回”顶部“从顶层命名空间重新开始search下一个模块。