在 Jupyter Notebook 中导入期间未找到模块

Posted

技术标签:

【中文标题】在 Jupyter Notebook 中导入期间未找到模块【英文标题】:Module Not found during import in Jupyter Notebook 【发布时间】:2017-08-24 12:16:19 【问题描述】:

我有以下包(和工作目录):

WorkingDirectory--
                 |--MyPackage--
                 |            |--__init__.py
                 |            |--module1.py
                 |            |--module2.py
                 |
                 |--notebook.ipynb

__init__.py 我有:

import module1
import module2

如果我尝试将 MyPackage 导入我的笔记本:

import MyPackage as mp 

我会收到ModuleNotFoundError: No module named 'module1'。但是,如果我在笔记本之外执行脚本,导入工作正常:如果我在同一目录中创建 test.py 并在笔记本中执行相同操作,则导入将正常工作。如果我在 __init__.py (import MyPackage.module1) 中使用完全限定名称,它将在笔记本中工作。

不同导入行为的原因是什么?

我已经确认笔记本的工作目录是WorkingDirectory

---更新------

确切的错误是:

C:\Users\Me\Documents\Working Directory\MyPackage\__init__.py in <module>()
---> 17 import module1

ModuleNotFoundError: No module named 'module1'

我的问题与可能的重复问题不同:

    笔记本能够找到包,但无法加载模块。这是通过用MyPackage.module1 替换module1 推断得出的,这表明它可能不是与PATH 相关的问题。

    我加入WorkingDirectory 并在那里启动服务器。工作目录应该是包含我的包的文件夹。

【问题讨论】:

"ImportError: No module named" when trying to run Python script的可能重复 @LouiseDavies 我更新了我的问题以解决重复问题。 我有一个类似的问题,它连接到一些没有所有软件包的旧内核;确保一次有一个,并且连接到默认端口 8888。 【参考方案1】:

我很确定这个问题是相关的,那里的答案会对你有所帮助:https://***.com/a/15622021/7458681

tl;dr 笔记本服务器的 cwd 始终是您启动服务器的基本路径,无论 import os os.getcwd() 是否正在运行。使用import sys sys.path.append("/path/to/your/module/folder")

我用一些与你指定的结构相同的虚拟模块运行它,在修改 sys.path 之前它不会运行,之后它会运行

【讨论】:

您的意思是将WorkingDirecotry 添加到PATHWorkingDirectory/MyPackage?后者有效,但前者无效。这是预期的行为吗?如果PATH 是问题所在,为什么在 init.py 中使用完全限定名称可以解决问题?【参考方案2】:

两行代码就能解决这个问题,

#list the current work dir
os.getcwd()
#change the current work dir
os.chdir()

改路径,导入模块,玩的开心。

【讨论】:

【参考方案3】:

如果您在 jupyter 环境上遇到 module not found,则必须将其安装在 jupyter 环境中,而不是在命令提示符下安装它

在 jupyter 上通过这个命令(对于 windows)

!pip 安装模块名称

之后,您可以轻松导入和使用它。 每当你想告诉 jupyter 这是系统命令时,你应该在你的命令前加上 (!)。

【讨论】:

请不要在多个问题上发布重复的答案(here 和 here)。一个答案很好。见Is it acceptable to add a duplicate answer to several questions?【参考方案4】:

您可以通过安装 import_ipynb 包来做到这一点。

pip install import_ipynb

假设要在A.ipynb中导入B.ipynb,可以如下:

A.ipynb:

import import_ipynb
import B as b

那么你就可以在A中使用B.ipynb的所有功能了。

【讨论】:

【参考方案5】:

原因是您的MyPackage/__init__.py 是从当前工作目录运行的。例如。在这种情况下来自WorkingDirectory。这意味着,解释器找不到名为 module1 的模块,因为它既不位于当前目录也未位于全局包目录中。

解决方法很少。例如,您可以像这样临时覆盖当前工作目录

cwd = os.getcwd()
csd = __path__[0]
os.chdir(csd)

然后,在完成像import module1 这样的所有包初始化操作后,使用os.chdir(cwd) 恢复“调用者”的工作目录。

这对我来说是一个非常糟糕的方法,因为例如,如果在初始化操作时引发异常,则不会恢复工作目录。您需要使用try..except 语句来解决此问题。

另一种方法是使用相对导入。详情请参阅documentation。

这是一个MyPackage/__init__.py 的示例,适用于您的示例:

from .module1 import *

但它几乎没有缺点,而是通过文档经验发现的。例如,你不能写像import .module1 这样的东西。


更新: 我发现即使import MyPackage 是从通常的python 控制台运行的,也会引发此异常。不是来自 IPython 或 Jupyter Notebook。所以这似乎不是 IPython 本身的问题。

【讨论】:

以上是关于在 Jupyter Notebook 中导入期间未找到模块的主要内容,如果未能解决你的问题,请参考以下文章

将虚拟环境安装的包导入 Jupyter Notebook

如何让 Jupyter Notebook 自动导入代码?

Jupyter Notebook从同一目录中的python文件导入类

Elasticsearch:使用 Jupyter Notebook 创建 Python 应用导入 CSV 文件

Elasticsearch:使用 Jupyter Notebook 创建 Python 应用导入 CSV 文件

使用常规 Jupyter Notebook 导入 PySpark 包