ipynb导入另一个ipynb文件


90

交互式Python(ipython)真是太神奇了,尤其是当您将所有内容快速地拼凑在一起时……并且这样做的方式很容易返回。

但是,似乎有趣的是具有多个ipython笔记本(ipynb文件)的用例。似乎一个笔记本似乎不应该与其他笔记本有关系,这很有意义,只是我想导入其他ipynb文件。

我看到的唯一解决方法是将* .ipynb文件转换为* .py文件,然后可以将其导入到笔记本中。只有一个文件可以容纳项目中的所有内容,这有点怪异,特别是如果我想真正推动代码重用(这不是python的核心宗旨吗?)。

我想念什么吗?这不是ipython笔记本的受支持用例吗?我可以使用另一种解决方案将ipynb文件导入另一个笔记本吗?我很乐意继续使用ipynb,但现在真的搞砸了我的工作流程:(



2
您可以使用启动笔记本服务器--script来保存笔记本的.py副本。在IPython 2.0中,您将能够%run使用笔记本。我们仍在研究更好的代码重用机制。
Thomas K

1
本示例说明如何将IPython笔记本作为模块导入,而不将重复项作为脚本导出。
明斯克

Answers:


130

在较新的Jupyter中,这确实很简单:

%run MyOtherNotebook.ipynb

5
%run MyOtherNotebook.ipynb为我完成了这项工作。(“否”)
Florian H

6
注意,此方法将完全运行子笔记本。您可以添加支票__name__ == '__main__' and '__file__' not in globals()以验证您是否在子笔记本中。(从blog.sicara.com/...
弗拉维安Hautbois

8
%run'MyOtherNotebook.ipynb'错误:root:u'MyOtherNotebook.ipynb.py'找不到文件。
user3673

1
@ Kocur4d感谢您修复!有趣的是,当我尝试它时,它对我有用(带引号),但是文档中的示例没有任何引号。
约翰多多

3
如果有人遇到过这种情况,您还可以使用完整路径,例如%run“ /path/to/my/file/notebook.ipynb”
Jeremie

33

如果要导入A.ipynbB.ipynb

import import_ipynb
import A

在中B.ipynb

import_ipynb我创建的模块是通过pip安装的:

pip install import_ipynb

这只是一个文件,并且严格遵守jupyter网站上的官方howto

PS它还支持之类的东西from A import foofrom A import *


@Crashpip install import-ipynb也可以工作并安装相同的软件包,但是由于python不允许您编写import import-ipynb并且考虑到它只是一个文件,因此pip install import_ipynb对我来说看起来更一致。
axil

3
有什么区别import nbimporterimport import_ipynb
Fractale

1
这在我使用Python 3的Jupyter中根本不起作用
Sebastialonso,

@Sebastialonso到底什么不起作用?描述您的操作以及看到的错误消息。理想情况是在github上打开票证。

@axil我有一个相同的错误,在Py3中对我不起作用。它给了我以下错误-ModuleNotFoundError:同一文件夹中不存在名为“ A”的模块PS:A.ipynb
Soman Dubey

10

!pip install ipynb

然后将另一个笔记本导入为

from ipynb.fs.full.<notebook_name> import *

要么

from ipynb.fs.full.<notebook_name> import <function_name>

确保所有笔记本位于同一目录中。

编辑1:您可以在此处查看官方文档-https: //ipynb.readthedocs.io/en/stable/

另外,如果您只想从笔记本中导入类和函数定义(而不是顶层语句),则可以使用ipynb.fs.defs代替ipynb.fs.full。完整的大写变量赋值也将得到评估。


如果我的文件名中包含空格怎么办?
Sameh

建议您不要在文件名中保留任何空格
Malgo

2
请注意,在上述两种情况下,导入的笔记本都将完整执行。该ipynb软件包还仅支持定义的部分执行。它是IPyhton的官方软件包,因此我认为这应该是公认的答案。
amka66

这样可以将笔记本导入文件夹中吗?例如MyFolder/book.ipynb
bones225

这看起来不错,但遇到例如%matplotlib内联时就会
掉线

7

从命令提示符安装ipynb

pip install import-ipynb

导入您的笔记本文件

import import_ipynb

现在使用常规的导入命令来导入文件

import MyOtherNotebook

最简单而又解释清楚的答案。谢谢!
可怜的犹太人

3

您可以使用import nbimporterimport notebookName


+ 1,nbimporter对我来说就像是一种符咒,也可以使用conda install -c conda-forge importnb
conda

2

上面提到的注释非常有用,但是很难实现。在您可以尝试的以下步骤中,我也尝试了并且它有效:

  1. 从笔记本以PY文件格式下载该文件(可以在“文件”选项卡中找到该选项)。
  2. 现在将下载的文件复制到Jupyter Notebook的工作目录中
  3. 您现在可以使用它了。只需将.PY文件导入ipynb文件

嗯...我将callee.ipync转换为callee.py文件,然后将callee.py文件与caller.ipync和我刚刚写的in caller.ipync一起上传到笔记本的同一文件夹下import callee,工作。
艾尔莎·林

ps IPython版本:5.1.0。
艾尔莎·林

1

问题是笔记本不是普通的python文件。.ipynb下面概述了导入文件的步骤:导入笔记本

我正在粘贴代码,因此,如果需要...,您可以进行快速复制和粘贴。请注意,最后我得到了import primes声明。当然,您必须更改它。我的文件名为primes.ipynb。从这一点开始,您可以像平常一样使用该文件中的内容。

希望有一个更简单的方法,但这直接来自文档。
注意:我使用的是jupyter而不是ipython。

import io, os, sys, types
from IPython import get_ipython
from nbformat import current
from IPython.core.interactiveshell import InteractiveShell


def find_notebook(fullname, path=None):
    """find a notebook, given its fully qualified name and an optional path

    This turns "foo.bar" into "foo/bar.ipynb"
    and tries turning "Foo_Bar" into "Foo Bar" if Foo_Bar
    does not exist.
    """
    name = fullname.rsplit('.', 1)[-1]
    if not path:
        path = ['']
    for d in path:
        nb_path = os.path.join(d, name + ".ipynb")
        if os.path.isfile(nb_path):
            return nb_path
        # let import Notebook_Name find "Notebook Name.ipynb"
        nb_path = nb_path.replace("_", " ")
        if os.path.isfile(nb_path):
            return nb_path


class NotebookLoader(object):
    """Module Loader for Jupyter Notebooks"""
    def __init__(self, path=None):
        self.shell = InteractiveShell.instance()
        self.path = path

    def load_module(self, fullname):
        """import a notebook as a module"""
        path = find_notebook(fullname, self.path)

        print ("importing Jupyter notebook from %s" % path)

        # load the notebook object
        with io.open(path, 'r', encoding='utf-8') as f:
            nb = current.read(f, 'json')


        # create the module and add it to sys.modules
        # if name in sys.modules:
        #    return sys.modules[name]
        mod = types.ModuleType(fullname)
        mod.__file__ = path
        mod.__loader__ = self
        mod.__dict__['get_ipython'] = get_ipython
        sys.modules[fullname] = mod

        # extra work to ensure that magics that would affect the user_ns
        # actually affect the notebook module's ns
        save_user_ns = self.shell.user_ns
        self.shell.user_ns = mod.__dict__

        try:
        for cell in nb.worksheets[0].cells:
            if cell.cell_type == 'code' and cell.language == 'python':
                # transform the input to executable Python
                code = self.shell.input_transformer_manager.transform_cell(cell.input)
                # run the code in themodule
                exec(code, mod.__dict__)
        finally:
            self.shell.user_ns = save_user_ns
        return mod


class NotebookFinder(object):
    """Module finder that locates Jupyter Notebooks"""
    def __init__(self):
        self.loaders = {}

    def find_module(self, fullname, path=None):
        nb_path = find_notebook(fullname, path)
        if not nb_path:
            return

        key = path
        if path:
            # lists aren't hashable
            key = os.path.sep.join(path)

        if key not in self.loaders:
            self.loaders[key] = NotebookLoader(path)
        return self.loaders[key]

sys.meta_path.append(NotebookFinder())

import primes

1

将Jupyter与现有或新的Python .py模块一起使用完全没有问题。在运行Jupyter的情况下,只需启动Spyder(或您选择的任何编辑器)即可在/ py文件中构建/修改模块类定义,然后根据需要将模块导入Jupyter。

使这一过程真正无缝的一件事是使用autoreload magic扩展。您可以在此处查看自动重新加载的文档:

http://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html

以下代码可在修改模块后自动重新加载该模块:

# autoreload sets up auto reloading of modified .py modules
import autoreload
%load_ext autoreload
%autoreload 2

请注意,我尝试了先前答复中提到的代码,以模拟将.ipynb文件作为模块加载,并使其正常工作,但是当您对.ipynb文件进行更改时,它会阻塞。看来您需要重新启动Jupyter开发环境才能重新加载.ipynb'模块',这对我来说是不可接受的,因为我正在对代码进行大量更改。


0

请确保您还在__init__.py所有其他.ipynb文件所在的包中添加了一个文件。

这是除了在nbviewer链接minrksyi上方。

我也有一些类似的问题,然后我写了解决方案以及指向我的公共Google Drive文件夹的链接,该文件夹有一个有效的示例:)

我的Stackoverflow帖子包含逐步实验和解决方案:

Jupyter Notebook:导入.ipynb文件并在其他给出错误的.ipynb文件中访问该方法

希望这对其他人也有帮助。谢谢大家!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.