Python - 同一目录中模块的绝对导入

14

我有这个包:

mypackage/
    __init__.py
    a.py
    b.py

我想从a模块导入东西到b模块,写在b模块里面有意义吗?

from mypackage.a import *

还是我应该只使用

from a import *

这两个选项都可以正常工作,我只是想知道哪个更好(第二个选项因为它在同一级别所以很合理,但我正在考虑第一个选项以避免冲突,例如如果系统正在运行包含文件a.py的文件夹中)。

2个回答

7
您可以安全地使用数字2,因为不应该有任何冲突-您将始终从与当前模块相同的包中导入模块。请注意,如果您的模块与标准库模块之一同名,则会导入该模块而不是标准模块。来自文档
当导入一个名为spam的模块时,解释器首先搜索具有该名称的内置模块。如果找不到,则在变量sys.path给出的目录列表中搜索名为spam.py的文件。sys.path从以下位置初始化:
- 包含输入脚本(或当前目录)的目录。 - PYTHONPATH(目录名称列表,与shell变量PATH具有相同的语法)。 - 安装相关的默认值。
初始化后,Python程序可以修改sys.path。正在运行的脚本所在的目录被放置在搜索路径的开头,位于标准库路径之前。这意味着该目录中的脚本将被加载,而不是库目录中同名的模块。除非有意替换,否则这是一个错误。有关更多信息,请参见标准模块部分。
选项from mypackage.a import *可以在整个项目中用于一致性的原因。在某些模块中,您仍然需要进行绝对导入。因此,您无需考虑模块是否在同一个包中,只需在整个项目中使用统一的样式即可。此外,这种方法更加可靠和可预测。 Python风格指南不建议使用相对导入:

强烈不建议使用相对导入进行包内导入。 对于所有导入,请始终使用绝对包路径。即使现在 PEP 328 在Python 2.5中已完全实现,其显式的 相对导入风格仍然被强烈反对;绝对导入更具 可移植性和可读性。

自从Python 2.5以来,包内相对导入的新语法被引入。现在你可以使用.来引用当前模块,..来引用上一级模块。请注意保留HTML标签。
from . import echo
from .. import formats
from ..filters import equalizer

5
你怎么知道 'a' 到底是不是与内置函数发生了冲突呢?隐式相对导入之所以被禁止,是因为它们不安全。 - MatthewWilkes
你是对的,内置模块将会被我们自己的同名模块所覆盖。 - Maksim Skurydzin
Python风格指南不推荐第一种方法:对我来说,看起来他们确实推荐第一种方法:“始终使用所有导入的绝对包路径”。 - banana
对不起,我的头脑和手已经异步了。已相应地更正答案。 - Maksim Skurydzin

5
你应该使用 from mypackage.a import things, you, want
此处有两个问题,其中一个是相对导入和绝对导入的语义在 Python 3 中发生了改变,并可以选择在 Python 2.6 和 2.7 中使用 __future__ 导入。通过使用 mypackage.a,您保证将获得您实际想要的代码,并且它将可靠地在未来的 Python 版本上工作。
第二件事是,您应该避免使用 import *,因为它可能会掩盖其他代码。如果 a.py 文件增加了一个名为 sum 的函数,它将悄悄地覆盖内置函数。当在其他模块中导入您自己的代码时,这尤其糟糕,因为您可能已经重用了变量或函数名称。
因此,您应该只导入您需要的特定函数。然后,在您的源代码上使用 pyflakes 将会警告您存在潜在冲突。

2
顺便说一句,from __future__ import absolute_import 在 Python 2.5 上也可以使用。 - jfs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接