首页 文章

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

提问于
浏览
64

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

或者使用_1485432中引入的显式相对导入:

# explicit relative
import ..A
import .B

什么是最pythonic的方式来做到这一点?

3 回答

  • 100

    绝对进口 . 从PEP 8:

    非常不鼓励包装内进口的相对进口 . 始终对所有导入使用绝对包路径 . 即使现在PEP 328 [7]已在Python 2.5中完全实现,但它的显式相对导入风格仍然是不鼓励的;绝对导入更便携,通常更具可读性 .

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

    import A.A
    import A.B.B
    

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

    你想要更明确的几个额外的击键将在他们试图找出你的命名空间时(特别是如果你迁移到3.x,其中一些包)将来保存其他人(也许你)很多时间名字已经改变) .

  • 38

    不再强烈建议不要使用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都反对从模块运行脚本:

    我在-1以及__main__机器的任何其他提议的twiddlings上都是-1 . 唯一的用例似乎是运行脚本,这些脚本恰好位于模块的目录中,我一直将其视为反模式 . 为了让我改变主意,你必须让我相信它不是 .

    关于此事的详尽讨论可以在SO上找到;回覆 . Python 3这是非常全面的:

  • 30

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

相关问题