代码之家  ›  专栏  ›  技术社区  ›  Daniel Hepper

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

  •  70
  • Daniel Hepper  · 技术社区  · 14 年前

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

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

    project.app1.views 进口 project.app1.models project.app2.models . 有两种方法可以做到这一点。

    绝对进口:

    import A.A
    import A.B.B
    

    或者使用显式的相对导入,如 Python 2.5 with PEP 328 :

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

    什么是最蟒蛇的方式来做这件事?

    3 回复  |  直到 5 年前
        1
  •  46
  •   Rafe Kettler    14 年前

    绝对进口。政治公众人物8:

    包内导入的相对导入量很高 气馁。 始终对所有导入使用绝对包路径。 即使现在PEP 328[7]已经在Python 2.5中完全实现了, 它明确相对进口的方式被积极地劝阻; 绝对导入更具可移植性,通常更具可读性。

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

    import A.A
    import A.B.B
    

    尤其是当您导入几个不同的命名空间时。如果您看到一些编写良好的项目/教程,其中包括从包内导入的内容,则它们通常遵循这种样式。

    当其他人(也许还有你)试图找出你的名称空间时(特别是当你迁移到3.x时,其中一些包的名称已经改变了),你所需要的几个额外的按键会在将来节省很多时间。

        2
  •  116
  •   Community Johnny    7 年前

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

    请看 this discussion 引用圭多本人的话:

    “这不主要是历史性的吗?直到新的相对导入语法 实施时,相对进口存在各种问题。这个 短期解决方案是建议不要使用它们。长期的 解决方案是实现一个明确的语法。现在是时候 撤回反建议。当然,不会落水 --我仍然觉得他们是有品位的,但他们有自己的位置。”

    操作程序正确链接 PEP 328 上面写着:

    提出了几个用例,其中最重要的是 能够重新安排大包装的结构而不必 编辑子包。此外,包中的模块不容易 导入本身而不使用相对导入。

    也可以看到几乎重复的问题 When or why to use relative imports in Python

    当然,它仍然是一个味道的问题。虽然使用相对导入更容易移动代码,但这也可能意外地破坏某些内容;重命名导入并没有那么困难。

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

    from __future__ import absolute_import
    

    在这种情况下,隐式相对导入将不再可能(例如。 import localfile 不会再工作了,只是 from . import localfile ). 对于清洁和未来证明行为,建议使用绝对进口。

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

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

    我对这件事和其他任何关于主要机器的建议都很满意。 唯一的用例似乎是运行恰好位于模块目录中的脚本,我一直将其视为反模式。 要想让我改变主意,你得说服我,事实并非如此。

    关于这件事的详尽讨论可以在上面找到。Python 3这非常全面:

        3
  •  31
  •   Brandon Rhodes    14 年前

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