从父目录内的python模块导入到子目录内的jupyter笔记本文件

del*_*onX 8 python python-module python-import jupyter-notebook

我有这样的文件结构:

project_folder/
     notebooks/
          notebook01.ipynb
          notebook02.ipynb
          ...
          notebookXY.ipynb
     module01.py
     module02.py
     module03.py
Run Code Online (Sandbox Code Playgroud)

.ipynb文件notebook/夹内的文件中,我想从module01.py, module02.py和导入类和函数module03.py

我在这个问题中找到了答案,可以在每个笔记本中使用以下代码行并每次将这些行作为第一个单元格运行:

import os
import sys
module_path = os.path.abspath(os.path.join('..'))
if module_path not in sys.path:
    sys.path.append(module_path)
Run Code Online (Sandbox Code Playgroud)

请问有更好的方法吗?如果.ipynb文件notebooks/夹中有很多文件,我是否必须在每个文件的开头粘贴这些代码行?有没有更好、更简约或更干净的方式?

Dav*_*ish 7

另一个解决方案是将所有 Python 模块(.py 文件)移动到一个文件夹中,并使它们成为可安装的包。如果将pip其安装到当前环境中,则可以将包导入到该环境中的任何笔记本中,无论文件夹结构如何。

因此,根据您的情况,您可以:

project_folder/
  notebooks/
    notebook01.ipynb
    notebook02.ipynb
    ...
    notebookXY.ipynb
  my_package/
    __init__.py
    module01.py
    module02.py
    module03.py
  setup.py
Run Code Online (Sandbox Code Playgroud)
  • __init__.py可以只是一个空文件,并告诉 Python“此文件夹中的所有内容都是包的一部分”
  • 有关setup.py中内容的说明,请参阅此处

基本的setup.py可以像这样简单:

import setuptools

setuptools.setup(
    name="my_package",
    version="0.0.1",
    description="A small example package",
    packages=setuptools.find_packages(),
    python_requires='>=3.7',
)
Run Code Online (Sandbox Code Playgroud)

安装它:

cd project_folder
pip install [-e] .
Run Code Online (Sandbox Code Playgroud)

包含可选-e标志将以“可编辑”模式安装my_package,这意味着将创建指向文件所在位置的符号链接,而不是将文件复制到虚拟环境中。

现在在任何笔记本中您都可以执行以下操作:

import my_package

或者

from my_package.module01 import <some object>

  • 您好,这是一个非常有用的答案,但是当我尝试从其中一个笔记本(notebook01.ipynb)以与上面相同的设置安装 my_package 时,它​​将无法工作,因为工作目录位于笔记本中,而不是父项目文件夹中。有没有办法很好的处理这个问题呢?也就是说,所有笔记本都是在工作目录设置为project_folder或其他解决方案的情况下创建的? (2认同)

agh*_*ast 5

尝试将 加入project_folder到您的PYTHONPATH环境变量中。这将允许您告诉 python 在该目录中搜索导入。

您可以在您的用户配置文件设置或启动脚本中执行此操作 - 而不是在 python 中。这是必须在 python 运行之前设置的东西。

  • 单击 Jupyter Notebook,我可以通过运行带有代码的单元格来实现:`sys.path.append(os.path.dirname(os.getcwd()))` 但它不能永久解决我的问题,直到我重新启动内核,它和我的Q体中的原始解决方案几乎相同 (2认同)