无法从模块导入子模块
cannot import submodule from a module
我的项目结构如下
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
现在init.py inside utils 目录包含以下代码。
# inside __init__.py
from . import utils_image_preprocess
from . import utils_image
from . import utils_tfrecord
运行 以上 init.py 文件给我一个错误:
ImportError: attempted relative import with no known parent package
test_utils.py inside tests 目录包含以下代码
# inside test_utils.py
from object_detection.utils import utils_image
虽然 运行 test_utils.py 我得到以下错误
ImportError: cannot import name 'utils_image' from 'object_detection.utils'
我已经完成了 this and this 并尝试按照那里提到的每个方面进行操作,但是关于在 init.py 中放入什么的详细信息尚不清楚。
这个问题似乎与 init.py 在不同目录中的结构有关。
我经历了很多,知道如果我们保留一个空的 init.py 文件,那么事情就会解决,但我不确定我的理解。
请告诉我
- 我在这里遗漏了什么以及我是否遵循正确的结构来打包我的代码?
- 如何解决这两个错误?
- 这个问题是否与在 IDE 中设置源有关,因为我正在使用 Vscode,而且我也看到很多地方都提到了这个问题。看到 here 了吗? (但也用 PyCharm 尝试了相同的代码并遇到了同样的错误)
您尝试过以下操作吗?
在您的 utils
__init__.py
中导入您的模块,如下所示:
from .utils_image_preprocess import <func1>... <rest of functions/classes you want to import>
from .utils_image import <func1>... <rest of functions/classes you want to import>
from .utils_tfrecord import <func1>... <rest of functions/classes you want to import>
然后在你的测试文件中做:
from object_detection.utils.utils_image import *
或
from object_detection.utils.utils_image import <func1>,...
此外,请确保您的模块中没有任何循环依赖项。例如将测试中的函数导入 util 模块,反之亦然
Python3 有 two types of packages
- 普通套餐
- 命名空间包
常规包包含 init.py 和命名空间包不需要 init.py
关于你的文件夹结构,是正确的,不需要改变。你只需要像这样导入
from utils import utils_image
没有提及 objects_detection,因为 objects_detection 只是一个命名空间包。
因此,当您从 objects_detection 文件夹外部引用 utils 模块时,它会很有用。
python 文档对命名空间包的描述如下:
A namespace package is a composite of various portions, where each portion contributes a subpackage to the parent package.
如果你想能够说...
from object_detection.utils import utils_image
... 那么显然 utils 目录必须是 object_detection 目录的子目录并且 不是同级目录,即在同一级别。
现在你的另一个错误:
ImportError: attempted relative import with no known parent package
除了说“init.py 文件上面的 运行 给我一个错误:”之外,您并没有具体说明在什么情况下会出现此错误。但是 如何 你是“运行”这些 py 文件还是什么意思?
如果发生这种情况时您正在执行脚本(否则您会得到这个错误吗?),脚本必须作为模块调用(因为脚本不能有相对导入 - 见下文)如下(我们将假定您要执行的脚本是 test_utils_image.py):
首先,object_detection的父目录,也就是Object_Detection,必须在系统中要搜索的目录路径以查找 import
语句中引用的模块和包。 一般,这可以通过多种方式完成,例如
- 您正在执行的脚本在Object_Detection中(脚本的目录自动添加到
sys.path
目录列表中以供搜索口译员)。
- 通过脚本在运行时将 Object_Detection 动态附加到
sys.path
目录列表。
- 将Object_Detection附加到PYTHONPATH环境变量。
上面的第 1 项不适用于这种特定情况,因为我们根据定义执行的模块不在 Object_Detection 目录中。
请注意,如果您的 类 最终将与 pip
一起安装,那么 site-packages 将是 的父目录object_detection,已经在 sys.path
.
然后你可以执行你的脚本:
python -m tests.test_utils_image
如果你想把这个.py文件作为脚本来执行,比如鼠标右键点击它就是VS Code,那么请看Relative imports for the billionth time,特别是脚本部分可以't import relative,这说明了一切——它不能工作!
要将其作为脚本调用,只需将相对导入转换为绝对导入。 事实上,PEP 8 Style Guide 表示:
Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages) if the import system is incorrectly configured (such as when a directory inside a package ends up on sys.path
):
我的项目结构如下
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
现在init.py inside utils 目录包含以下代码。
# inside __init__.py
from . import utils_image_preprocess
from . import utils_image
from . import utils_tfrecord
运行 以上 init.py 文件给我一个错误:
ImportError: attempted relative import with no known parent package
test_utils.py inside tests 目录包含以下代码
# inside test_utils.py
from object_detection.utils import utils_image
虽然 运行 test_utils.py 我得到以下错误
ImportError: cannot import name 'utils_image' from 'object_detection.utils'
我已经完成了 this and this 并尝试按照那里提到的每个方面进行操作,但是关于在 init.py 中放入什么的详细信息尚不清楚。
这个问题似乎与 init.py 在不同目录中的结构有关。
我经历了很多,知道如果我们保留一个空的 init.py 文件,那么事情就会解决,但我不确定我的理解。
请告诉我
- 我在这里遗漏了什么以及我是否遵循正确的结构来打包我的代码?
- 如何解决这两个错误?
- 这个问题是否与在 IDE 中设置源有关,因为我正在使用 Vscode,而且我也看到很多地方都提到了这个问题。看到 here 了吗? (但也用 PyCharm 尝试了相同的代码并遇到了同样的错误)
您尝试过以下操作吗?
在您的 utils
__init__.py
中导入您的模块,如下所示:
from .utils_image_preprocess import <func1>... <rest of functions/classes you want to import>
from .utils_image import <func1>... <rest of functions/classes you want to import>
from .utils_tfrecord import <func1>... <rest of functions/classes you want to import>
然后在你的测试文件中做:
from object_detection.utils.utils_image import *
或
from object_detection.utils.utils_image import <func1>,...
此外,请确保您的模块中没有任何循环依赖项。例如将测试中的函数导入 util 模块,反之亦然
Python3 有 two types of packages
- 普通套餐
- 命名空间包
常规包包含 init.py 和命名空间包不需要 init.py
关于你的文件夹结构,是正确的,不需要改变。你只需要像这样导入
from utils import utils_image
没有提及 objects_detection,因为 objects_detection 只是一个命名空间包。
因此,当您从 objects_detection 文件夹外部引用 utils 模块时,它会很有用。
python 文档对命名空间包的描述如下:
A namespace package is a composite of various portions, where each portion contributes a subpackage to the parent package.
如果你想能够说...
from object_detection.utils import utils_image
... 那么显然 utils 目录必须是 object_detection 目录的子目录并且 不是同级目录,即在同一级别。
现在你的另一个错误:
ImportError: attempted relative import with no known parent package
除了说“init.py 文件上面的 运行 给我一个错误:”之外,您并没有具体说明在什么情况下会出现此错误。但是 如何 你是“运行”这些 py 文件还是什么意思?
如果发生这种情况时您正在执行脚本(否则您会得到这个错误吗?),脚本必须作为模块调用(因为脚本不能有相对导入 - 见下文)如下(我们将假定您要执行的脚本是 test_utils_image.py):
首先,object_detection的父目录,也就是Object_Detection,必须在系统中要搜索的目录路径以查找 import
语句中引用的模块和包。 一般,这可以通过多种方式完成,例如
- 您正在执行的脚本在Object_Detection中(脚本的目录自动添加到
sys.path
目录列表中以供搜索口译员)。 - 通过脚本在运行时将 Object_Detection 动态附加到
sys.path
目录列表。 - 将Object_Detection附加到PYTHONPATH环境变量。
上面的第 1 项不适用于这种特定情况,因为我们根据定义执行的模块不在 Object_Detection 目录中。
请注意,如果您的 类 最终将与 pip
一起安装,那么 site-packages 将是 的父目录object_detection,已经在 sys.path
.
然后你可以执行你的脚本:
python -m tests.test_utils_image
如果你想把这个.py文件作为脚本来执行,比如鼠标右键点击它就是VS Code,那么请看Relative imports for the billionth time,特别是脚本部分可以't import relative,这说明了一切——它不能工作!
要将其作为脚本调用,只需将相对导入转换为绝对导入。 事实上,PEP 8 Style Guide 表示:
Absolute imports are recommended, as they are usually more readable and tend to be better behaved (or at least give better error messages) if the import system is incorrectly configured (such as when a directory inside a package ends up on
sys.path
):