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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43120112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 22:32:19  来源:igfitidea点击:

Module Not found during import in Jupyter Notebook

pythonpython-3.xjupyter-notebookpython-importpython-module

提问by Ryan

I have the following package (and working directory):

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

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

In __init__.pyI have:

__init__.py我有:

import module1
import module2

If I try to import MyPackage into my notebook:

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

import MyPackage as mp 

I will get ModuleNotFoundError: No module named 'module1'. But import works fine if I execute the script outside a notebook: if I create test.pyin the same directory and do the same as in the notebook the import would work properly. It will work inside the notebook if I use fully qualified name in __init__.py(import MyPackage.module1).

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

What's the reason for different import behavior?

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

I have confirmed the working directory of the notebook is WorkingDirectory.

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

---Update---------

- -更新 - - - - -

Exact error is:

确切的错误是:

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

ModuleNotFoundError: No module named 'module1'

My problem differs from the possible duplicate:

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

  1. The notebook was able to find the package, but only unable to load the module. This was inferred from substituting module1with MyPackage.module1worked well and suggests it may not be a problem related with PATH.

  2. I cded into WorkingDirectoryand started the server there. The working directory should be the folder containing my package.

  1. 笔记本能够找到包,但无法加载模块。这是从替换module1withMyPackage.module1工作得很好推断出来的,并表明它可能与PATH.

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

回答by Louise Davies

I'm pretty sure this issue is related and the answer there will help you: https://stackoverflow.com/a/15622021/7458681

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

tl;dr the cwd of the notebook server is always the base path where you started the server, no matter was running import os os.getcwd()says. Use import sys sys.path.append("/path/to/your/module/folder").

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

I ran it with some dummy modules in the same structure as you had specified, and before modifying sys.pathit wouldn't run and after it would

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

回答by Volodymyr Sendetskyi

The reason is that your MyPackage/__init__.pyis ran from the current working directory. E.g. from WorkingDirectoryin this case. It means, that interpreter cannot find the module named module1since it is not located in either current or global packages directory.

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

There are few workarounds for this. For example, you can temporarily override a current working directory like this

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

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

and then, after all a package initialization actions like import module1are done, restore "caller's" working directory with os.chdir(cwd).

然后,在完成所有包初始化操作import module1后,使用os.chdir(cwd).

This is quite a bad approach as for me, since, for example, if an exception is raised on initialization actions, a working directory would not be restored. You'll need to play with try..exceptstatements to fix this.

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

Another approach would be using relative imports. Refer to the documentationfor more details.

另一种方法是使用相对导入。有关更多详细信息,请参阅文档

Here is an example of MyPackage/__init__.pythat will work for your example:

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

from .module1 import *

But it has few disadvantages that are found rather empirically then through the documentation. For example, you cannot write something like import .module1.

但是它几乎没有缺点,而这些缺点是凭经验而不是通过文档发现的。例如,您不能编写类似import .module1.



Upd:I've found this exception to be raised even if import MyPackageis ran from usual python console. Not from IPython or Jupyter Notebook. So this seems to be not an IPython itself issue.

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