Python ModuleNotFoundError - 从子目录导入到子目录

时间:2021-04-21 09:21:35

标签: python jupyter-notebook

首先:我知道有很多关于此的问题,但是我发现的问题都没有解决我的问题。

设置

我有以下文件夹结构:

WorkingDirectory(WD)
                   |---------- data
                   |              |
                   |              |-- __init__.py (empty)
                   |              |-- dataset.py (with import: from software.utils import *)
                   |              |-- test.ipynb (with import: from dataset import *)
                   |
                   |-------software
                   |              |
                   |              |-- __init__.py (empty)
                   |              |-- utils.py (with import: from software.utils import *)
                   |
                   |-- main.py (with imports from software and data)

以及以下 pythonm 版本:

  • python -V 给出 3.7.10
  • ipython -V 给出 7.22.0

问题

如果我运行 python main.py,我不会收到任何错误,但如果我尝试在 from dataset import * 文件中执行 test.ipynb,我会收到错误:

ModuleNotFoundError                       Traceback (most recent call last)
<ipython-input-4-a20c81312677> in <module>
----> 1 from dataset import *

~/WD/data/dataset.py in <module>
     15 
     16 
---> 17 from software.utils import *

ModuleNotFoundError: No module named 'software'

所以一般来说,从 dataset.py 导入是有效的,但是来自 software.utils.py 的“子导入”不起作用。我不确定这是否是 ipython 问题,因为它与 python 一起工作(如果我执行 main.py,它正在工作)?

2 个答案:

答案 0 :(得分:1)

通常这些类型的问题围绕当前工作目录的隐式添加到 sys.path e.g. python包搜索路径。
放一个

import sys

print(sys.path)

并查看常规 python 调用和通过 Jupyter 的两个输出有何不同。 常规的 python 调用可能会隐含地或通过解释器的 -m 标志调用你的 WD,而 Jupyter Notebook 不会。 解决此问题的唯一干净方法是使用一致的方式调用脚本。 要么像在此 answer 中那样向您的脚本添加某种 sys.path 调整,要么将您的软件包安装到您的系统软件包存储库中,Jupyter Notebook 也在其中寻找软件包。

答案 1 :(得分:1)

主要问题似乎是由于路径问题无法导入模块。这似乎是因为您引用了从父目录开始的导入,但由于您位于父目录内的目录中,因此不能。

您可以在 test.ipynb 中的所有代码之前使用它,

import os, sys
currentdir = os.path.dirname(os.path.realpath(__file__))
parentdir = os.path.dirname(currentdir)
sys.path.append(parentdir)

此代码基本上附加了您的父目录的路径,因此您可以毫无问题地导入。至少我听到的好的做法是不要玩弄 sys.path ,但是由于需要出现,它可以完成工作。如果可以,我建议你稍微改变一下结构。