在 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
添加到PATH
或WorkingDirectory/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从同一目录中的python文件导入类
Elasticsearch:使用 Jupyter Notebook 创建 Python 应用导入 CSV 文件