Dan*_*per 73 python package python-import
我想知道在Python应用程序中导入包的首选方法.我有这样的包结构:
project.app1.models
project.app1.views
project.app2.models
Run Code Online (Sandbox Code Playgroud)
project.app1.views进口project.app1.models和project.app2.models.有两种方法可以实现这一点.
绝对进口:
import A.A
import A.B.B
Run Code Online (Sandbox Code Playgroud)
或者使用PEP 328在Python 2.5中引入的显式相对导入:
# explicit relative
from .. import A
from . import B
Run Code Online (Sandbox Code Playgroud)
什么是最pythonic的方式来做到这一点?
Ste*_*ano 116
不再强烈建议不要使用Python相对导入,但在这种情况下强烈建议使用absolute_import.
请看引用Guido本人的讨论:
"这不是历史性的吗?在实施新的相对导入语法之前,相对导入存在各种问题.短期解决方案是建议不使用它们.长期解决方案是实现明确的语法.现在现在是时候撤回反对推荐了.当然,不要过分 - 我仍然觉得他们有一种后天的味道;但他们有自己的位置."
OP正确链接PEP 328,其中说:
提出了几个用例,其中最重要的是能够重新排列大包的结构,而无需编辑子包.此外,如果没有相对导入,包内的模块不能轻易导入.
另请参阅几乎重复的问题何时或为何在Python中使用相对导入
当然,它仍然是品味的问题.虽然使用相对导入来移动代码更容易,但这也可能会意外地破坏事物; 并重命名进口并不困难.
要从PEP 328强制执行新行为,请使用:
from __future__ import absolute_import
Run Code Online (Sandbox Code Playgroud)
在这种情况下,隐式相对导入将不再可能(例如,import localfile将不再有效from . import localfile).为了清洁和面向未来的行为,建议使用absolute_import.
一个重要的警告是,由于 PEP 338和PEP 366,相对导入需要将python文件作为模块导入 - 您无法执行具有相对导入的file.py或者您将获得ValueError: Attempted relative import in non-package.
在评估最佳方法时应考虑此限制.在任何情况下,Guido都反对从模块运行脚本:
我在这方面以及__main__机器的任何其他提议的twiddlings上都是-1.唯一的用例似乎是运行脚本,这些脚本恰好位于模块的目录中,我一直将其视为反模式.为了让我改变主意,你必须让我相信它不是.
关于此事的详尽讨论可以在SO上找到; 回覆.Python 3这是非常全面的:
Raf*_*ler 45
绝对进口.从PEP 8:
不鼓励进行包装内进口的相对进口.始终对所有导入使用绝对包路径.即使现在PEP 328 [7]已在Python 2.5中完全实现,但它的显式相对导入风格仍然是不鼓励的; 绝对导入更便携,通常更具可读性.
显式相对导入是一个很好的语言功能(我猜),但它们并不像绝对导入那样明确.更易读的形式是:
import A.A
import A.B.B
Run Code Online (Sandbox Code Playgroud)
特别是如果您导入几个不同的命名空间.如果你看一些包含从包中导入的编写良好的项目/教程,它们通常都遵循这种风格.
你想要更明确的几个额外的击键将在他们试图找出你的命名空间时(特别是如果你迁移到3.x,其中一些包)将来保存其他人(也许你)很多时间名字已经改变).
Bra*_*des 31
相对导入不仅让你可以在不改变数十个内部导入的情况下自由重命名你的包,但我也成功地解决了涉及循环导入或命名空间包等问题的某些问题,因为他们不会将Python发送回top"从顶级命名空间开始重新搜索下一个模块.