首页 > 解决方案 > ImportError : 在没有已知父包的情况下尝试相对导入

问题描述

我正在学习使用 python 编程,但从包中的模块导入时遇到问题。我正在使用带有 Python 3.8.2 64 位的 Visual Studio 代码。

我的项目目录

.vscode
├── ecommerce
│   ├── __init__.py
│   ├── database.py
│   ├── products.py
│   └── payments
│       ├── __init__.py
│       ├── authorizenet.py
│       └── paypal.py
├── __init__.py
└── main.py

ecommerce/products.py我的文件中:

#products.py
from .database import Database
p = Database(3,2)

这样我就可以从文件中导入Database类。ecommerce/database.py但我得到错误

ImportError : Attempted relative import with no known parent package

标签: pythonpylint

解决方案


Python 文档和实验看来,相对导入(涉及 .、.. 等)仅在以下情况下才有效

  1. 导入模块有一个__name__以外的__main__,而且,
  2. 导入模块的__name__名称是 pkg.module_name,也就是说,它必须从目录层次结构中的上方导入(要有一个父 pkg 作为它的一部分__name__。)

或者

导入模块是通过包含父 pkg as 的模块语法指定的python -m pkg.module,在这种情况下它__name__仍然是__main__,因此它作为脚本运行,但相对导入将起作用。这里__package__设置并用于查找父包 while __name__is __main__; 更多在这里

[毕竟,这似乎是确定相对进口是否/如何起作用的关键__package__。表示脚本或模块(即,或)。指示相对导入发生在包中的哪个位置,并且顶部需要在.]sys.path__name____main__module_name__package____package__sys.path

因此,继续 @AmitTendulkar 的示例,如果您作为> python main.py或从项目根目录运行它,> python -m main或者> python -m ecommerce.products从该根目录输入交互式 python 和import main,或者import ecommerce.productsproducts.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__of /home/jj/sub, - 工作None中的模块的绝对导入sys.path,相对导入失败。

> python -m sub.modsys.path, __package__of /home/jj, sub- 模块的绝对导入sys.path工作,相对导入工作相对于sys.path+ __package__

添加更有帮助

import sys    
print("In module products sys.path[0], __package__ ==", sys.path[0], __package__)

等在每个文件中进行调试。


推荐阅读