无法从模块导入子模块

use*_*244 1 python oop package python-3.x

我的项目有以下结构

Object_Detection/
                 setup.py
                 setup.cfg
                 requirement.txt
                 object_detection/
                                  models
                                  __init__.py #contains from . import models
                 tests/ 
                       # inside tests dir
                       test_utils_image.py
                       __init__.py #empty
                 utils/
                      # inside utils dir
                      __init__.py #inside 
                      utils_image_preprocess.py
                      utils_image.py
                      utils_tfrecord.py
Run Code Online (Sandbox Code Playgroud)

现在utils 目录中的init .py 包含以下代码。

# inside __init__.py
from . import utils_image_preprocess
from . import utils_image
from . import utils_tfrecord
Run Code Online (Sandbox Code Playgroud)

在init .py 文件之上运行会出现错误:

ImportError: attempted relative import with no known parent package
Run Code Online (Sandbox Code Playgroud)

测试目录中的 test_utils.py 包含以下代码

# inside test_utils.py
from object_detection.utils import utils_image
Run Code Online (Sandbox Code Playgroud)

运行 test_utils.py 时出现以下错误

ImportError: cannot import name 'utils_image' from 'object_detection.utils'
Run Code Online (Sandbox Code Playgroud)

我已经经历过这个这个,并尝试遵循那里提到的每个方面,但关于在init.py中放入什么的细节尚不清楚。

这个问题似乎与不同目录中init.py的结构有关。

我经历过各种情况,并且知道如果我们保留一个空的init .py 文件,那么事情就会解决,但我不确定我的理解。

请告诉我

  1. 我在这里缺少什么以及我是否遵循正确的结构来打包我的代码?
  2. 如何解决这两个错误?
  3. 这个问题是否与在 IDE 中设置源有关,因为我使用的是 Vscode,而且我也看到很多地方都提到了这一点。看这里?(但也尝试使用 PyCharm 执行相同的代码并遇到相同的错误)

Boo*_*boo 5

如果你想能够说...

from object_detection.utils import utils_image
Run Code Online (Sandbox Code Playgroud)

...那么显然utils目录必须是object_detection目录的子目录,而不是同级目录,即处于同一级别。

现在针对您的另一个错误:

ImportError: attempted relative import with no known parent package
Run Code Online (Sandbox Code Playgroud)

除了说“在init .py 文件之上运行给我一个错误:”之外,您并没有真正指定在什么情况下会收到此错误。但是你如何“运行”这些 py 文件或者这意味着什么?

如果发生这种情况时您正在执行脚本(否则您会如何收到此错误?),则必须将脚本作为模块调用(因为脚本不能具有相对导入 - 见下文),如下所示(我们假设脚本您尝试执行的是test_utils_image.py):

首先, object_detection的父目录(即Object_Detection)必须位于要搜索的目录的系统路径中,以查找import语句中引用的模块和包。一般来说,这可以通过多种方式完成,例如

  1. 您正在执行的脚本位于Object_Detection中(脚本的目录会自动添加到sys.path解释器要搜索的目录列表中)。
  2. 通过脚本在运行时动态将Object_Detection添加到目录列表中。sys.path
  3. Object_Detection附加到PYTHONPATH环境变量。

上面的第 1 项不适用于这种特定情况,因为我们根据定义执行的模块不在Object_Detection目录中。

请注意,如果您的类最终将与 一起安装pip,则site-packages将是object_detection的父目录,该目录已经位于sys.path.

然后你可以执行你的脚本:

python -m tests.test_utils_image
Run Code Online (Sandbox Code Playgroud)

如果您想将此 .py 文件作为脚本执行,例如通过鼠标右键单击它是 VS Code,那么请参阅十亿次相对导入,特别是脚本无法导入相对部分,这说明了一切——这行不通!

要将其作为脚本调用,只需将相对导入转换为绝对导入即可。事实上,PEP 8 风格指南说:

建议绝对导入,因为如果导入系统配置不正确(例如当包内的目录以 结尾时),它们通常更具可读性并且往往表现更好(或至少给出更好的错误消息)sys.path


归档时间:

查看次数:

6604 次

最近记录:

4 年,6 月 前