从另一个 ipynb 文件导入 ipynb 文件?
- 2025-02-12 10:03:00
- admin 原创
- 69
问题描述:
交互式 Python (ipython) 简直令人惊奇,特别是当你在即时地将一切拼凑在一起时……并且以一种很容易返回的方式进行。
然而,似乎有趣的是拥有多个 ipython 笔记本 (ipynb 文件) 的用例。显然,笔记本不应该与其他笔记本有关系,这是有道理的,只是我很想导入其他 ipynb 文件。
我看到的唯一解决方法是将我的 .ipynb 文件转换为 .py 文件,然后可以将其导入我的笔记本。让一个文件包含项目中的所有内容有点奇怪,特别是如果我真的想推动代码重用(这不是 Python 的核心原则吗?)。
我是不是漏掉了什么?这不是 ipython 笔记本支持的用例吗?有没有其他解决方案可以将 ipynb 文件导入另一个笔记本?我很想继续使用 ipynb,但它现在真的搞乱了我的工作流程 :(
解决方案 1:
在较新的 Jupyter 中,这非常简单:
%run MyOtherNotebook.ipynb
请参阅此处了解详情。
官方文档:%run
IPython 魔法命令
解决方案 2:
从命令提示符安装我的帮助库:
pip install import-ipynb
从你的笔记本导入:
import import_ipynb
现在导入你的 .ipynb 笔记本,就像它是一个 .py 文件一样
import TheOtherNotebook
这个import-ipynb
模块只是一个文件,它严格遵守jupyter 网站上的官方操作指南。
PS 它还支持from A import foo
诸如from A import *
等
PPS 与子目录配合使用:import A.B
解决方案 3:
跑步
!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
。 完整的大写变量赋值也会得到评估。
解决方案 4:
从命令提示符安装 ipynb
pip install import-ipynb
导入你的笔记本文件
import import_ipynb
现在使用常规导入命令导入您的文件
import MyOtherNotebook
解决方案 5:
%run YourNotebookfile.ipynb 工作正常;
如果你想导入特定模块,那么只需在 ipynb 后添加导入命令,即 YourNotebookfile.ipynb 具有 def Add()
那么你就可以使用它
%run YourNotebookfile.ipynb import Add
解决方案 6:
上述注释非常有用,但实现起来有点困难。您可以尝试以下步骤,我也试过了,而且有效:
以 PY 文件格式从您的笔记本中下载该文件(您可以在文件选项卡中找到该选项)。
现在将下载的文件复制到 Jupyter Notebook 的工作目录中
现在您就可以使用它了。只需将 .PY 文件导入 ipynb 文件即可
解决方案 7:
你可以import nbimporter
使用import notebookName
解决方案 8:
问题是笔记本不是普通的 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
解决方案 9:
使用 Jupyter 与现有或新的 Python .py 模块完全没有问题。在 Jupyter 运行时,只需启动 Spyder(或您选择的任何编辑器)在 .py 文件中构建/修改模块类定义,然后根据需要将模块导入 Jupyter 即可。
让这一切变得无缝衔接的一件事是使用 autoreload 魔法扩展。你可以在这里看到 autoreload 的文档:
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“模块”,这对我来说是不可接受的,因为我正在对我的代码进行大量更改。
解决方案 10:
请确保您还在__init__.py
包含所有其他 .ipynb 文件的文件包中添加了一个文件。
minrk
这是对上面提供的nbviewer 链接的补充syi
。
我也遇到了类似的问题,然后我写了解决方案以及一个指向我的公共谷歌驱动器文件夹的链接,其中有一个工作示例:)
我的 Stackoverflow 帖子包含逐步实验和解决方案:
Jupyter Notebook:导入 .ipynb 文件并在其他 .ipynb 文件中访问其方法时出现错误
希望这也能帮助其他人。谢谢大家!
解决方案 11:
虽然 '%run childNotebook.ipynb' 命令是一个非常简单且有用的解决方案(如前面的答案中所述),但当子文件也在使用另一个 '%run grandChildNotebook.ipynb' 但位于另一个目录中时,您应该谨慎使用它! 它可能导致文件重复运行,并且也容易出错(因为子文件不再使用与其父文件相同的路径,而在运行时,Jupyter 假定它这样做!)
为了解决上述问题,一种解决方案可能是:在导入任何文件之前,首先检查当前目录的位置,然后根据该位置采取行动。以下是一个例子:
if 'myFolder' in os.getcwd():
%run graindChildNotebook.ipynb
else:
%run myFolder/grandChildNotebook.ipynb
在上面的例子中,首先检查我们是否在“myFolder”目录中。如果是,我们会发现“grandChildNotebook”位于同一目录中,并且正常运行它就足够了。否则,我们需要通过添加此文件所在文件夹的名称来运行它。
请注意,这只是一个例子,您应该根据您的情况制定个性化的解决方案!