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

标签 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
from .. import A
from . import B

最pythonic的方法是什么?

最佳答案

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

请参阅 this discussion引用 Guido 自己的话:

"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."

OP 正确链接 PEP 328上面写着:

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.

另见几乎重复的问题 When or why to use relative imports in Python

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

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

from __future__ import absolute_import

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

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

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

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.

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

关于python - Python 模块的绝对与显式相对导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4209641/

相关文章:

java - 在哪里可以找到 org.apache.common 库

Java 如何制作包启动器,以打开项目中的包

perl - 为什么符号的封装限定会导致使用更少的内存,即使符号是本地导入的?

具有模块级全局变量的 python 模块

Python 正则表达式仅检查子字符串是否后跟子字符串

python - 无法从辅音中确定元音

Python:从列表中删除具有相同楼层函数的数字

python - 在 python 中连接到 url

python - 无法运行已安装的库

python - 从父目录的子目录导入 python 模块