从
Python文档和实验中看来,相对导入(涉及.,..等)仅在以下情况下生效:
1. 导入模块具有除
__main__
之外的
__name__
;
2. 导入模块的
__name__
为pkg.module_name,即必须从目录层次结构的上层进行导入(以其父级pkg作为
__name__
的一部分)。
或者
导入模块是通过包含父包的模块语法指定的,如
python -m pkg.module
,此时其
__name__
仍为
__main__
,因此它将作为脚本运行,但相对导入将会生效。这里设置并使用了
__package__
来查找父包,而
__name__
为
__main__
;
更多信息请参见此处。
[经过所有这些内容,似乎
__package__
和
sys.path
是确定相对导入是否以及如何工作的关键。
__name__
表示脚本或模块(即
__main__
或
module_name
)。
__package__
指示与哪个包相对导入关联,
__package__
的顶部需要位于
sys.path
中。]
因此,以@AmitTendulkar的示例为例,如果在项目根目录下运行
> python main.py
或
> python -m main
或
> python -m ecommerce.products
,或从该根目录输入交互式python并导入
main
或
import ecommerce.products
,则products.py中的相对导入将起作用。
但是,如果您在ecommerce目录内执行
> python products.py
或
> python -m products
,或者从该ecommerce目录输入交互式python并导入
products
,则它们将失败。
添加以下内容会很有帮助:
print("In module products __package__, __name__ ==", __package__, __name__)
在每个文件中添加 etc.
以进行调试。
更新:
导入的工作方式取决于 sys.path
和 __package__
,而不是 __name__
。
从 /home/jj
发出的 > python sub/mod.py
具有 sys.path
、__package__
为 /home/jj/sub
,None
- 在 sys.path
中的模块的绝对导入工作正常,相对导入失败。
> python -m sub.mod
具有 sys.path
、__package__
为 /home/jj
、sub
- 在 sys.path
中的模块的绝对导入工作正常,相对导入相对于 sys.path
+ __package__
工作。
更有帮助的是添加
import sys
print("In module products sys.path[0], __package__ ==", sys.path[0], __package__)
在每个文件中等等以进行调试。