ImportError:尝试进行相对导入,但没有已知的父包。
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)
这样我就可以从ecommerce/database.py
文件中导入Database
类。但我收到错误
ImportError : Attempted relative import with no known parent package
据 Python 文档和实验结果显示,相对导入(涉及 .、.. 等符号)仅在以下两种情况下起作用:
1. 导入模块的__name__不是__main__,而且
2. 导入模块的__name__形如 pkg.module_name,也就是说,它必须是从目录结构上方导入的(使其__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并import main或import ecommerce.products,则产品文件夹中的相对导入将起作用。但如果你在 ecommerce 目录中,输入 > 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__)
等内容进行调试会更有帮助。