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
Module Not found during import in Jupyter Notebook
提问by Ryan
I have the following package (and working directory):
我有以下包(和工作目录):
WorkingDirectory--
|--MyPackage--
| |--__init__.py
| |--module1.py
| |--module2.py
|
|--notebook.ipynb
In __init__.py
I 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.py
in 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:
我的问题与可能的重复不同:
The notebook was able to find the package, but only unable to load the module. This was inferred from substituting
module1
withMyPackage.module1
worked well and suggests it may not be a problem related withPATH
.I cded into
WorkingDirectory
and started the server there. The working directory should be the folder containing my package.
笔记本能够找到包,但无法加载模块。这是从替换
module1
withMyPackage.module1
工作得很好推断出来的,并表明它可能与PATH
.我进入
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.path
it wouldn't run and after it would
我用一些与您指定的结构相同的虚拟模块运行它,在修改sys.path
它之前它不会运行,之后它会
回答by Volodymyr Sendetskyi
The reason is that your MyPackage/__init__.py
is ran from the current working directory. E.g. from WorkingDirectory
in this case. It means, that interpreter cannot find the module named module1
since 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 module1
are 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..except
statements 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__.py
that 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 MyPackage
is 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 本身的问题。