Python3.5 从子目录导入不起作用

Python3.5 import from subdirectory doesn't work

我有一堆 python 脚本,只是想通过将大部分脚本放入子目录来构建它们。但是,当我尝试从子目录加载脚本时,python 会给出不同的错误消息,具体取决于我尝试导入子目录脚本的方式。

我的子目录如下所示:

io
├── dataset_creator.py
└── read_data.py

在父目录的脚本中,当我这样做时

from io import dataset_creator

发生此错误:

ImportError: cannot import name 'dataset_creator'

当我做的时候

import io.dataset_creator

发生此错误:

ImportError: No module named 'io.dataset_creator'; 'io' is not a package

我也将 __init__.py 插入到 io/ 中,但它根本没有帮助,并且在 io/ 前面加了一个点,但没有成功。 python 文档说我应该添加 __init__.py 然后一切都应该工作,基本上(据我解释)。

有人可以帮我吗?如果我遗漏了一些重要信息,请告诉我,我会添加它。

干杯, 雅各布

编辑:

正如你们中的许多人所说,io 已经是 python 中的另一个包,因此将我的 io/ 重命名为不同的名称解决了问题(同时还有 __init__.py)。非常感谢你! 我知道有多个正确答案,但是,我只能将一个标记为正确答案,抱歉。

它可能会失败,因为 io 已经是 built-in module

我在这里回答过类似的问题

将您的父路径附加到 Pythonpath: import sys sys.path.append("/path/to/parentfolder")

您可以使用 os.path.dirname(__file__) 获取文件的绝对路径而不是硬编码路径。

将 __init__.py 添加到您的父文件夹和 io 文件夹,将其作为目录以外的 python 包。

导入模块: import io.dataset_creator as dcreator

parent/
  -- app.py
  -- io/
      --dataset_creator.py
      --read_data.py

在你里面app.py:

import sys
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
import io.dataset_creator as dcreator

我在 Python 3.5.1 上测试时也发生了这种情况。

将目录 io 重命名为其他名称(我使用 my_io)解决了问题。这是我的测试用例:

main.py
my_io
├── module.py
└── something.py

当我更改目录名称时,两个模块都正确导入了。我建议您将 io 目录更改为类似的目录以避免这种情况。

我认为这一定与某个名为 io 的内部 Python 模块有关,该模块在某种程度上存在冲突。

名称 io 已被 a standard library module 使用。由于它是解释器使用的非常基本的模块之一,它会在启动过程中加载,在您的任何代码运行之前。这意味着当 Python 看到您导入 io.dataset_creator 的请求时,它已经在 sys.modules 中获得了一个 io 模块。由于该模块不是包,它不会尝试加载您在 io 包中编写的其他子模块(即使您设置了模块搜索路径以便您的包在标准库之前).

您应该重命名您的 io 包。一种选择是将它放在另一个包中(mypackage.io.dataset_creator 应该可以正常工作)。您也可以将名称 io 替换为更具体的名称(例如 myproject_io)。

重现问题:

mkdir io
touch dataset_creator.py
touch read_data.py
python3 -c 'from io import dataset_creator'
python3 -c 'import io.dataset_creator'

给出错误信息。

解法:

  1. 创建另一个名为 "io" 的 sub-directory 并将文件放在那里。
  2. 使用不同于 "io" 的名称,因为同名模块已经存在。

解释:

您已经在 io 目录中,因此不需要指定 "io"。你可以简单地做:

python3 -c 'import dataset_creator'
python3 -c 'import read_data'

并且在 python 文件中添加函数或 class 后:

def hello_world():
    print("hello world")

你可以这样导入:

python3 -c 'from read_data import hello_world'

要在 io 模块伞下组织您的代码,请按如下方式创建另一个 io 目录并使用它来存储您的 python 代码:

ia (parent dir where you do the import)
├── ia
│   ├── dataset_creator.py
│   └── read_data.py
├── .gitignore
├── requirements.txt
├── setup.py
└── README.md

python3 -c 'import ia.dataset_creator'

注意我将目录重命名为 "ia" 并且已经存在一个 "io" 模块 (ref)。