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

时间:2017-02-09 17:42:17

标签: python python-import

我有一堆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)。非常感谢你! 我知道有多个正确答案,但是,我可以将其标记为正确,抱歉。

5 个答案:

答案 0 :(得分:2)

由于io已经是built-in module

,它可能失败了

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

我在这里回答了类似的问题Using exec on a file in a different directory causes module import errors

将您的父路径附加到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

答案 3 :(得分:0)

当我测试它时,我和Python 3.5.1也发生过这种情况。

将目录io重命名为其他内容(我使用my_io)修复了问题。这是我的测试用例:

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

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

我认为这必须与一些名为io的内部Python模块有关,这种模块在某种程度上是冲突的。

答案 4 :(得分:0)

重新创建问题:

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

提供错误消息。

<强>解决方案:

  1. 创建另一个名为&#34; io&#34;的子目录。把文件放在那里。
  2. 使用与&#34; io&#34;不同的名称,因为该名称的模块已经存在。
  3. <强>解释

    您已经在io目录中,因此您不需要指定&#34; io&#34;。你可以这样做:

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

    一旦你在python文件中添加了一个函数或类:

    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'
    

    注意我将目录重命名为&#34; ia&#34;以及已经有一个&#34; io&#34;存在的模块(ref)。