简体   繁体   English

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

[英]Module Not found during import in Jupyter Notebook

I have the following package (and working directory):我有以下 package(和工作目录):

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' .我会得到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.但如果我在笔记本外执行脚本,导入工作正常:如果我在同一目录中创建test.py并执行与笔记本中相同的操作,导入将正常工作。 It will work inside the notebook if I use fully qualified name in __init__.py ( import MyPackage.module1 ).如果我在__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.笔记本能找到package,但只能加载模块。 This was inferred from substituting module1 with MyPackage.module1 worked well and suggests it may not be a problem related with PATH .这是从用MyPackage.module1替换module1推断出来的,效果很好,表明它可能不是与PATH相关的问题。

  2. I cded into WorkingDirectory and started the server there.我进入WorkingDirectory并在那里启动服务器。 The working directory should be the folder containing my package.工作目录应该是包含我的 package 的文件夹。

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. tl; dr 笔记本服务器的 cwd 始终是您启动服务器的基本路径,无论运行import os os.getcwd()说。 Use import sys sys.path.append("/path/to/your/module/folder") .使用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之前它不会运行,之后它会

two lines of code will solve this,两行代码就可以解决这个问题,

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

change the path, and import module, have fun.改变路径,导入模块,玩得开心。

if you face module not found on jupyter environment you had to install it on jupyter environment instead of installing it on command prompt如果您在jupyter 环境找不到模块,则必须在 jupyter 环境中安装它,而不是在命令提示符下安装它

by this command(for windows) on jupyter通过 jupyter 上的这个命令(对于 Windows)

pip install module name pip 安装模块名称

after that you can easily import and use it.之后,您可以轻松导入和使用它。 Whenever you want to tell jupyter that this is system command you should put (. ) before your command每当你想告诉 jupyter 这是系统命令时,你应该把 (. ) 放在你的命令之前

You can do that by installing the import_ipynb package.您可以通过安装import_ipynb package 来做到这一点。

 pip install import_ipynb

Suppose you want to import B.ipynb in A.ipynb , you can do as follows:假设你想在A.ipynb中导入B.ipynb ,你可以这样做:

In A.ipynb :A.ipynb

 import import_ipynb import B as b

Then you may use all the functions of B.ipynb in A .然后你可以在A中使用B.ipynb的所有功能。

The best way to tackle this issue is to create a virtual env and point your kernel to that virtual environment:解决此问题的最佳方法是创建一个虚拟环境并将您的 kernel 指向该虚拟环境:

Steps:脚步:

  1. python -m venv venv
  2. source venv/bin/activate
  3. ipython kernel install --user --name=venv
  4. jupyter lab
  5. go to the jupyter lab ->kernel-->change kernel-->add the venv from the dropdown

Now if your venv has the package installed, jupyter lab can also see the package and will have no problem importing the package.现在,如果您的 venv 安装了 package,jupyter 实验室也可以看到 package,并且导入 package 也没有问题。

My problem was that I used the wrong conda enviroment when using Vs Code .我的问题是我在使用Vs Code时使用了错误的 conda 环境。

Enter your conda enviroment输入您的 conda 环境

conda activate **enviroment_name**

To check where a module is installed you can enter python interactive mode by writing python or python3.要检查模块的安装位置,您可以通过编写 python 或 python3 进入 python 交互模式。 Then importing cv2然后导入cv2

 import cv2

Then to see where this module is installed然后看看这个模块安装在哪里

print(cv2.__file__)

You will see the installed path of the module.您将看到模块的安装路径。 My problem was that my vs code kernel was set to the wrong enviroment.我的问题是我的 vs 代码 kernel 设置为错误的环境。 This can be changed in the top right corner for vs code.这可以在 vs 代码的右上角进行更改。

hope this helps希望这可以帮助

this happened to me when I moved my journal into a new directory while the Jupyter lab server was running.当我在 Jupyter 实验室服务器运行时将我的日记移动到一个新目录时,这发生在我身上。 The import broke for that journal, but when I made a new journal in the same directory I just moved to and used the same import, it worked.该日志的导入中断了,但是当我在同一目录中创建新日志时,我刚刚移动到并使用了相同的导入,它起作用了。 To fix this I:为了解决这个问题,我:

  1. Went to the root dir for my project.去了我的项目的根目录。
  2. Searched for all folders labeled “ pycache搜索所有标有“ pycache ”的文件夹
  3. Deleted all “ pycache ” folders that were found in my root and subfolders.删除了在我的根文件夹和子文件夹中找到的所有“ pycache ”文件夹。
  4. Restarted Jupyter lab server重新启动 Jupyter 实验室服务器

Once Jupyter lab restarts and compiles your code, the “ pycache ” folders will be regenerated.一旦 Jupyter 实验室重新启动并编译您的代码,“ pycache ”文件夹将重新生成。 Also the pycache folders have two leading and trailing “_”, but stackoverflow is formatting the pycache's without them pycache 文件夹也有两个前导和尾随“_”,但 stackoverflow 正在格式化没有它们的 pycache

The best solution by far (for me) is to have a kernel for each environment you are working in. Then, with that kernel defined, all you have to do is to update this kernel's environment variables to look at your project folder where your modules are located.到目前为止(对我而言)最好的解决方案是为您正在使用的每个环境设置一个 kernel。然后,定义了 kernel,您所要做的就是更新此内核的环境变量以查看您的模块所在的项目文件夹位于。

Steps (using pip ):步骤(使用pip ):

  1. pip install ipykernel (if not installed already) pip install ipykernel (如果尚未安装)
  2. source activate <your environment name>
  3. python -m ipykernel install --user --name <your environment name> --display-name "<a display name>" (where python -m ipykernel install --user --name <your environment name> --display-name "<a display name>" (其中is the name you want to give to your kernel and是你想给你的 kernel 的名字,并且is just a name used for display by jupyter.只是 jupyter 用于显示的名称。
  4. Once you ran the command above, it will output the location of the kernel configuration files.运行上面的命令后,它将 output 配置文件的位置 kernel 。 Eg: C:\Users\<your user name>\AppData\Roaming\jupyter\kernels\<selected environment name> .例如: C:\Users\<your user name>\AppData\Roaming\jupyter\kernels\<selected environment name> Go to this folder and open the kernel.json file. Go到这个文件夹,打开kernel.json文件。
  5. Add the following entry to this file:将以下条目添加到此文件中:
"env": {
   "PYTHONPATH": "${PYTHONPATH};<the path to your project with your modules>
 }

Good reference about the kernel install command here .关于 kernel 安装命令很好的参考。

The reason is that your MyPackage/__init__.py is ran from the current working directory.原因是您的MyPackage/__init__.py是从当前工作目录运行的。 Eg from WorkingDirectory in this case.例如,在这种情况下来自WorkingDirectory It means, that interpreter cannot find the module named module1 since it is not located in either current or global packages directory.这意味着,该解释器找不到名为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) .然后,在所有 package 初始化操作(如import module1 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 documentation for 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.更新:我发现即使import MyPackage从通常的 python 控制台运行也会引发此异常。 Not from IPython or Jupyter Notebook.不是来自 IPython 或 Jupyter Notebook。 So this seems to be not an IPython itself issue.所以这似乎不是 IPython 本身的问题。

LOOK NO FURTHER.不要再看了。 Here is the simple solution.这是简单的解决方案。

You want to be able to type in a notebook cell to install packages from inside a Jupyter notebook.您希望能够输入笔记本单元格以从 Jupyter 笔记本中安装包。 To install your example package from within a Jupyter notebook, you want to type the following in a normal cell still in normal editing mode:要从 Jupyter 笔记本中安装示例 package,您需要在仍处于正常编辑模式的正常单元格中键入以下内容:

%pip install PyPDF2 %pip 安装 PyPDF2

That uses the pip magic command that insures the installation occurs in the environment that is backing the kernel underlying the notebook.这使用了 pip 魔术命令,确保安装发生在支持笔记本电脑底层 kernel 的环境中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM