将py文件导入Jupyter Notebook的另一个目录中

Gau*_*sal 8 python-import python-3.x

我的问题与有关。我在Jupyter Notebook中使用Python 3.6。我的项目目录是/user/project。在此目录中,我正在构建许多模型,每个模型都有自己的文件夹。但是,有一个通用的functions.py文件,其中包含我要在所有模型中使用的功能。所以,我想保留functions.py在文件中/user/project,但可以从一个调用它.ipynb的文件中/user/project/model1/user/project/model2等...我怎样才能做到这一点?

adh*_*dhg 22

假设您有一个名为Jupyter的文件夹,并且您希望从另一个名为nn_webserver 的文件夹中导入模块(员工)。

可视化它:

在此处输入图片说明

做这个:

import sys
import os

module_path = os.path.abspath(os.path.join('..'))
if module_path not in sys.path:
    sys.path.append(module_path+"\\nn_webserver")

from employee import motivation_to_work
Run Code Online (Sandbox Code Playgroud)

在此处查看来自@metakermit 的其他信息

  • 与使用绝对路径的另一个答案相比,我更喜欢这个相对路径。即使您将整个项目安装在不同的系统上,相对路径仍然有效,而绝对路径则需要调整。 (2认同)

hon*_*oon 13

没有简单的方法可以将python文件导入另一个目录。这与jupyter笔记本无关

这是您的问题的3种解决方案

  1. 您可以添加包含要导入的文件的目录,然后将其导入路径。像这样
import sys  
sys.path.insert(0, '/path/to/application/app/folder')

import file
Run Code Online (Sandbox Code Playgroud)
  1. 您可以通过__init__.py在要导入的文件夹中保存一个空文件来创建本地模块。关于文件夹层次结构,您必须考虑一些奇怪的规则

  2. 您可以为要导入的文件创建模块,然后将其全局安装。

  • 选项 1 可能更好,如 `sys.path.insert(1, '/path/to/application/app/folder')`,因为 path[0] 是为脚本路径(或 REPL 中的 '')保留的。 (4认同)
  • 我相信您发布的“奇怪的规则”链接已移至此处 https://docs.python.org/3/tutorial/modules.html (3认同)

Gus*_*s B 11

我一直在思考这个问题,因为我不喜欢这个sys.path.append()答案。我建议的解决方案使用内置的 Jupyter magic 命令来更改当前工作目录。假设您有以下文件结构:

\n
project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 model1\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 notebook1.ipynb\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 model2\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 notebook2.ipynb\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 functions.py\n
Run Code Online (Sandbox Code Playgroud)\n

无论您想functionsnotebook1.ipynb还是导入notebook2.ipynb,您都可以简单地在导入包的单元格之前添加一个包含以下行的单元格:

\n
%cd ..\n
Run Code Online (Sandbox Code Playgroud)\n

这会将当前工作目录更改为笔记本的父目录,然后将函数模块的路径添加到 Python 将检查包的默认位置。导入functions

\n
project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 model1\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 notebook1.ipynb\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 model2\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 notebook2.ipynb\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 functions.py\n
Run Code Online (Sandbox Code Playgroud)\n

如果您想要导入的同一包目录中有多个模块,则这将类似地工作:

\n
project\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 model1\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 notebook1.ipynb\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 model2\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 notebook2.ipynb\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 package\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 functions1.py\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 functions2.py \n
Run Code Online (Sandbox Code Playgroud)\n

您可以导入这两个模块functions1,如下functions2所示package

\n
%cd ..\n
Run Code Online (Sandbox Code Playgroud)\n

编辑:如下所述,如果包含 magic 命令的单元运行多次(当前工作目录将在每次重新运行该命令时更改为上面的目录),则本地导入将不再起作用。为了防止这种情况发生,该%cd ..命令应该位于笔记本顶部和导入之前的自己的单元格中(而不是与导入位于同一单元格中) ,这样它就不会多次运行。重新启动内核并运行所有单元将重置当前工作目录,但仍会返回所需的导入/结果。

\n

  • 这不是一个好的解决方案。每次运行单元时,“%cd ..”都会给您不同的结果(将工作目录进一步上移一个级别) (5认同)

Dil*_*hat 5

我建议functions.py在您的虚拟环境中作为包安装。这样做有一些好处:

  1. 您可以functions.py从位于任何地方的任何 iPython 笔记本访问文件,但在给定的环境(内核)中。
  2. 一旦你改变了functions.py文件中的任何函数,你就不需要一次又一次地重新加载你的 iPython 笔记本。它会自动重新加载每次更改。

这是如何做到的:

  • 在您的项目文件夹中创建setup.py文件 ( https://docs.python.org/2/distutils/setupscript.html )
  • 激活您的虚拟环境,转到您的项目位置,并使用此命令 pip install -e .
  • 然后,在您的 iPython 笔记本中:

    %load_ext 自动重载

    %自动重载 1

    %aimport yourproject.functions

    从函数导入 *

就是这样!


Zep*_*lag 5

我已经通过创建在该目录中的符号链接解决了过去这个问题Jupyter笔记本位于就是了负载库,使蟒蛇的行为仿佛模块处于正确的路径。因此,对于上面的示例,您将在Jupyter单元内的每个目录中运行一次以下命令:

!ln -s /user/project/functions.py functions.py
Run Code Online (Sandbox Code Playgroud)

然后你可以导入

import functions
Run Code Online (Sandbox Code Playgroud)

注意:我只在 Linux 和 Mac Os 上尝试过这个,所以我不能保证 Windows。


Ale*_*lex 5

除了 adhg 的答案之外,我建议使用 Pathlib,以实现 Linux/Windows/WSL 路径格式之间的兼容性:

\n

假设以下文件夹结构:

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 work\n|   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 notebook.ipynb\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 my_python_file.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 py\n|   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80modules\n|   |    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80__init__.py # empty\n|   |    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80preparations.py\n|   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80__init__.py # empty\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tools.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80.git\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 README.md\n
Run Code Online (Sandbox Code Playgroud)\n

加载tools.pypreparations.pymy_python_file.py(或在笔记本中notebook.ipynb):

\n
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 work\n|   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 notebook.ipynb\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 my_python_file.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 py\n|   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80modules\n|   |    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80__init__.py # empty\n|   |    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80preparations.py\n|   \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80__init__.py # empty\n|   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 tools.py\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80.git\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 README.md\n
Run Code Online (Sandbox Code Playgroud)\n