ImportError:尝试进行相对导入,但没有已知的父包。

12 浏览
0 Comments

ImportError:尝试进行相对导入,但没有已知的父包。

这个问题已经在这里有了答案:

Python 3中的相对导入

我正在学习使用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

admin 更改状态以发布 2023年5月21日
0
0 Comments

因为您正在使用Python 3.8版本,所以导入稍微有些不同,但我认为这应该可以工作:

请使用以下之一:

from database import Database
#Database is the class

或者尝试:

import database.Database

最后,以下是非常安全且最佳实践的做法:

from . import Database  
# The '.' (dot) means from within the same directory as this __init__.py module grab the Database class.

0
0 Comments

据 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/subNone - sys.path 中的模块的绝对导入可以工作,相对导入失败。

> python -m sub.mod 具有 sys.path__package__/home/jjsub - sys.path 中模块的绝对导入可以工作,相对导入相对于 sys.path + __package__

在每个文件中添加

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

等内容进行调试会更有帮助。

0