从Python docs 和实验看来,相对导入(涉及 .、.. 等)仅在以下情况下才有效
- 导入模块有一个
__name__,而不是__main__,此外,
- 导入模块的
__name__ 是pkg.module_name,即,它必须从目录层次结构中的上方导入(要将父pkg 作为__name__ 的一部分。)
或
导入模块是通过包含父 pkg 的模块语法指定的 python -m pkg.module,在这种情况下,它的 __name__ 仍然是 __main__,因此它作为脚本运行,但相对导入将起作用。这里设置了__package__,用于查找父包,而__name__为__main__; more here.
[毕竟,__package__ 和 sys.path 似乎是确定相对导入是否/如何工作的关键。 __name__ 表示脚本或模块(即__main__ 或module_name)。 __package__ 表示相对导入发生在包中的哪个位置,__package__ 的顶部需要在 sys.path 中。]
所以,继续@AmitTendulkar 的示例,如果您从项目根目录以> python main.py 或> python -m main 或> python -m ecommerce.products 运行它,或者从该根目录和import main 或@ 输入交互式python 987654345@ products.py 中的相对导入将起作用。
但如果您在电子商务目录中> python products.py 或> python -m products,或者从该电子商务目录输入交互式python 和import products,它们将失败。
添加有帮助
print("In module products __package__, __name__ ==", __package__, __name__)
等等。在每个文件中进行调试。
更新:
导入的工作方式取决于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__)
等等。在每个文件中进行调试。