在Jupyter笔记本中的另一个目录中导入py文件

时间:2018-03-13 19:14:05

标签: python-3.x python-import

我的问题与this有关。我在Jupyter Notebook中使用Python 3.6。我的项目目录是/user/project。在这个目录中,我构建了许多模型,每个模型都有自己的文件夹。但是,有一个常见的functions.py文件,其中包含我想在所有模型中使用的函数。因此,我希望将functions.py文件保留在/user/project中,但可以通过.ipynb/user/project/model1等中的/user/project/model2文件进行调用...我可以这样做吗?

7 个答案:

答案 0 :(得分:5)

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

以下是您的问题的两种解决方案

  1. 您可以将包含要导入的文件的目录添加到路径中,然后导入该文件。像这样

    import sys
    sys.path.insert(0,'/ path / to / application / app / folder')

    导入文件

  2. 您可以为要导入的文件创建一个模块并将其全局安装

答案 1 :(得分:1)

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

  1. 您可以从任意位置但在给定环境(内核)的任何iPython笔记本中访问functions.py文件。
  2. 一旦更改了functions.py文件中的任何功能,就不需要一次又一次地重新加载iPython Notebook。它将自动重新加载每个更改。

这是完成操作的方法:

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

    %load_ext自动重新加载

    %autoreload 1

    %a导入yourproject.functions

    从函数导入*

就是这样!

答案 2 :(得分:1)

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

形象化:

enter image description here

执行此操作:

from sympy import *
import numpy as np
import matplotlib.pyplot as plt

x = symbols('x')
equation = x**2 + 2 #OK = x*exp(-x**2/10) OR x**2 + 2
firstDeriv = equation.diff(x)
secondDeriv = firstDeriv.diff(x)
criticalPoints = list(solveset(firstDeriv, x))
criticalPointsY = [equation.subs(x, a) for a in criticalPoints]
xx = np.linspace(-10, 10, 100)
lam_f= lambdify(x, [equation, firstDeriv, secondDeriv])
yy=[elem if  type(elem) == np.ndarray else np.full(len(xx), elem) for elem in lam_f(xx)]
plt.plot(xx, np.transpose(yy))
plt.plot(criticalPoints, criticalPointsY, 'k*')
plt.show()

查看来自@metakermit的其他信息here

答案 3 :(得分:1)

过去,我已经通过在 Jupyter 笔记本所在的目录中创建一个指向其要加载的库的符号链接来解决此问题,从而使python 行为,就好像模块在正确的路径中一样。因此,对于上面的示例,您将在 Jupyter 单元格内每个目录一次运行以下命令

!ln -s /user/project/functions.py functions.py

然后您可以导入

import functions

注意:我只在Linux和Mac Os上尝试过此操作,因此我不能担保Windows。

答案 4 :(得分:1)

发现自己的情况与 OP 完全相同,打算创建多个笔记本,因此希望将它们组织在不同的子文件夹中

尝试过这似乎可以满足我的需要并且对我来说似乎更干净

import os
os.chdir(os.path.dirname(os.path.dirname(os.getcwd())))

我的函数在上面两层所以嵌套了两个os.path.dirname(不同的文件夹结构可能只有一个或多个)

刚刚实现它并且工作正常,顺便说一句,我正在使用 JupyterLab 开始......函数所在的两个级别以上

答案 5 :(得分:1)

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

project
├── model1
|   └── notebook1.ipynb
├── model2
|   └── notebook2.ipynb
└── functions.py

无论您想从 functionsnotebook1.ipynb 导入 notebook2.ipynb,您只需在导入包的单元格之前添加以下行的单元格:

%cd ..

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

import functions

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

project
├── model1
|   └── notebook1.ipynb
├── model2
|   └── notebook2.ipynb
└── package
    ├── functions1.py
    └── functions2.py 

您可以像这样从 functions1 导入模块 functions2package

from package import functions1, functions2

答案 6 :(得分:0)

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

假定以下文件夹结构:

.
├── work
|   ├── notebook.ipynb
|   └── my_python_file.py
├── py
|   ├──modules
|   |    ├──__init__.py # empty
|   |    └──preparations.py
|   ├──__init__.py # empty
|   └── tools.py
├──.git
└── README.md

要将tools.pypreparations.py加载到my_python_file.py(或笔记本notebook.ipynb中)中:

import sys
from pathlib import Path

# in jupyter (lab / notebook), based on notebook path
module_path = str(Path.cwd().parents[0] / "py")
# in standard python
module_path = str(Path.cwd(__file__).parents[0] / "py")

if module_path not in sys.path:
    sys.path.append(module_path)

from modules import preparations
import tools
...