Jupytext介绍推荐帖 - 作为Markdown文档或Python脚本的Jupyter notebooks
Jupyter笔记本是一种很好的方式,可以交互式地编写Python代码,并将文档、程序输出和数据可视化与产生的代码连在一起。许多IDE原生支持Jupyter笔记本,Jupyter笔记本服务器和JupyterLab环境也是编写笔记本的有效途径。但在引擎盖下,Jupyter笔记本只是一个JSON文档,而该文档的内容往往不是人类可以读懂的。正因为如此,它可能在你的版本控制系统中产生混乱的差异。Jupytext是一个Jupyter插件,可以自动将Jupyter笔记本保存为各种人类可读(和可编辑)的输出。它还允许将这些其他文件中的变化同步回笔记本文件(.ipynb
)本身。
你为什么要使用Jupytext?
有几个很好的理由可以考虑使用Jupytext。首先,你可能正在为在你的笔记本中正确进行版本控制而苦恼。我的关于版本控制的文章描述了这种情况,并给出了一些背景和解决这个问题的好办法,但它们未必对每种情况都完美。使用像nbdime这样的专门的差异工具会使差异更容易浏览,但最终,单个笔记本文件(即.ipynb
文件)包含代码、输出和元数据。所有这些都可能改变并污染你的差异,使版本管理成为一个挑战。
考虑Jupytext的第二个原因是,如果你喜欢在标准的Jupyter笔记本创作环境之外工作。也许你最喜欢在PyCharm或Visual Studio Code这样的IDE中写代码。或者你使用Vim或Emacs这样的文本编辑器,并喜欢你最喜欢的编辑器的全部功能。也许你在IPython会话中编写和测试一些代码,并且喜欢这样的笔记本,因为那里的代码单元很容易被打乱顺序。你也可能想在没有网络浏览器的情况下,在终端(也许是通过SSH连接)中工作笔记本。
第三个原因是能够更有效地处理笔记本和笔记本的内容,特别是 Python 源代码。例如,如果源代码是以Python文件这样一种更常见的格式存储的,那么就有许多工具可以用来检查代码,包括linters和formatters/beautifiers。
我们将看一下Jupytext如何支持这三种情况的几个例子。
安装和设置
Jupytext很容易用pip来安装。
pip install jupytext --upgrade
如果你使用的是Anaconda,则可以用它来安装。
conda install jupytext -c conda-forge
你很可能也会使用Jupyter Notebook或Lab环境。如果是这样,重新启动你的进程,在前端拾取Jupytext扩展。
笔记本或实验室的基本使用
了解Jupytext如何工作的最简单的方法是从一个简单的例子开始。在之前关于笔记本版本控制的文章中,我们用这个笔记本作为例子。这只是一个简单的笔记本,其中包括一个使用matplotlib
的绘图。在你设置了一个安装了matplotlib的Jupyter笔记本(或JupyterLab)环境后,你可以在Jupyter笔记本中打开这个笔记本(运行jupyter notebook
)。当你这样做时,你应该在文件菜单中看到一个Jupytext条目。勾选如下所示的数值,将你的笔记本同步到一个Python文件中。
Jupytext增加了菜单选项,按图示选择,以遵循该范例
首先,如果你主要想在脚本或Markdown文件中工作(我稍后会讲到所有的格式),你应该关闭Jupyter的自动保存功能。如果你主要想在Jupyter笔记本中工作,完成后只在脚本文件中检查,你可以让自动保存功能处于启用状态。
一旦笔记本与脚本输出配对,该文件就会在与笔记本相同的目录下创建。在我的例子中,这意味着文件jupyter_git_example.py
被创建。它看起来像这样。
# ---
# jupyter:
# jupytext:
# formats: ipynb,py:percent
# text_representation:
# extension: .py
# format_name: percent
# format_version: '1.3'
# jupytext_version: 1.13.0
# kernelspec:
# display_name: Python 3
# language: python
# name: python3
# ---
# %%
import matplotlib.pyplot as plt
plt.plot([x**2 for x in range(100)])
# %%
这种格式被称为percent
格式,那些特殊的注释 (# %%
) 表示笔记本的单元。
循环旅行
关于这个文件,你应该注意几件事。Jupytext会试着取其中一个文件的最新版本,用它来生成另一个。因此,例如,如果你更新了笔记本,然后手动保存它(因为你关闭了自动保存功能),Jupytext将刷新.py
文件。反之亦然,如果你编辑.py
文件,它将更新笔记本中的匹配单元。试试吧:在文本编辑器中对.py
文件做一个小的编辑,然后保存它(例如,将绘图改为使用0.5
,而不是2
)。然后,在笔记本中点击 "保存 "图标。Jupyter会警告你,磁盘上的文件已经改变,并给出三个选项。
- 取消 - 回到你已经看过的内容,但它与磁盘上保存的内容不一致。
- 重新加载 - 用保存在磁盘上的内容重新加载笔记本(现在与
.py
文件中的内容一致)。 - 覆盖 - 将在Jupytext刚刚更新的
.ipynb
文件上保存你的笔记本。
在这种情况下,你想从磁盘重新加载。单元格中的代码将被更新以符合你的编辑。然而,你需要知道,它并不执行该单元格。输出仍然会反映x**2
而不是x**0.5
。另外,你正在运行的 Python 会话不会更新任何变量,因为这些代码还没有被执行。你可以重新执行这个单元,以获取运行实例中的变化。上面这个例子可能看起来很混乱,但我认为它非常有效地展示了如何思考 Jupytext 的使用场景。
让我们更详细地考虑这三种使用场景。
版本控制
首先,如果你正在寻找一个有效的笔记本版本控制选项,你可以简单地安装Jupytext,将其与你想使用的输出格式配对,并在每次可提交的修改中检查生成的文件。你会得到干净的差异,用于历史跟踪。
在更复杂的情况下,比如分支和合并,你可以很容易地先对生成的脚本或Markdown进行合并,然后用Jupytext重新生成输出笔记本。Jupytext包括一个命令行工具,所以在笔记本环境之外更新文件很容易。
jupytext --to notebook notebook.py # generates notebook.ipynb from notebook.py, using comment markers
我在这里强调一下,当你重新生成.ipynb
文件时,它将不包含任何输出。你仍然要决定你是否要在笔记本文件中检查输出。如果你这样做,你需要在提交到版本控制之前重新执行笔记本(例如,通过使用Jupyter笔记本,或jupytext --execute
,或papermill)。
用其他工具进行编码
喜欢使用Jupytext的第二个原因是在IDE或文本编辑器中进行编码和编辑。在这种情况下,你的脚本或Markdown文件将是你工作的主要文件,而笔记本可以根据需要自动或手动生成和执行。使用这种方法,你可以得到清洁差异的所有好处,如果你喜欢使用你的IDE或者在Markdown环境中更舒服,你仍然可以使用笔记本的格式来向其他人发布结果。这是两个世界的最佳选择。
代码质量工具
使用Jupytext的第三个优势领域是自动化代码检查和其他QA工具。由于你可以将笔记本转换成常规的Python代码,你可以自动运行pylint、flake8或black等linter/validators。如果Python代码隐藏在笔记本文件中,那么就更难验证它是否符合你的组织的编码标准。
Jupytext的文档还描述了使用预提交框架与常见的预提交钩子的集成。你可以确保每次笔记本代码提交到git时,都会被验证。
Jupytext支持很多格式,不仅仅是Markdown
上面的例子将笔记本文件同步到Python源文件,但还有很多其他的格式选择。
有多种markdown格式支持。
- Jupytext Markdown - 一个简单的Markdown格式
- R Markdown- RStudio中的格式
- MyST- 标记的结构化文本
- PandocMarkdown - 用于Pandoc,通用文件转换器。它还可以转换笔记本(比如我用来写这篇文章的笔记本!)。
- Quarto- 一个基于Pandoc的科学出版系统
Jupytext还支持多种类型的脚本输出,以及多种语言,不仅仅是Python。这使得普通的代码文件也能生成笔记本。Jupytext将特殊的注释解析为指令,然后将按照脚本中指定的元数据生成单独的笔记本单元。使用每种格式都有好处和坏处,而且大多数格式都支持完整的往返转换,正如我们讨论的那样。Jupytext能够理解下列脚本格式。
- light - 一种为Jupytext项目创建的格式,单元格的开始和结束标记是
# +
,而# -
- nomarker - light的一个版本,但完全没有标记。这种格式不能被循环使用。
- percent - 标记被放在代码中,采用这种格式。
# %% Optional title [cell type] key="value"
- hydrogen - 与百分数非常相似,但它没有注释出Jupyter的魔法。
可能的问题
在配置中加入Jupytext的主要问题之一就是多了一块复杂的东西。如果你想对已完成的笔记本与输出进行签入和版本控制,你现在需要提交两个文件,而不是一个。这对你来说可能并不值得,这取决于你的环境。
另一个问题是,Jupytext是由命令行和官方的Jupyter创作工具支持的,但不是由所有其他IDE完全支持的,所以如果你使用一个不同的工具,你必须适应在命令行上进行转换。几乎在所有情况下,我都会说如果你打算在Jupyter中做更多的工作,就值得学习如何做。
最后,像往常一样,你需要严格确保你的笔记本输出单元与生成它们的代码一致。保证这一点的最好方法是,每次更新笔记本时,在提交之前,在内核重启后执行整个笔记本。你可以把这个再生步骤自动化,但真正的长篇笔记本可能会使这个步骤显得很繁琐。只是要注意,Jupytext可能会更新笔记本文件,而你可能没有意识到这一点。
Jupytext是一个很好的插件,对于那些喜欢在Markdown或普通源文件中工作的人,以及那些练习使用代码验证工具的人来说,将非常有用。
python
The postJupytext - Jupyter notebooks as Markdown documents or Python scriptsappeared first onwrighters.io.
转载自:https://juejin.cn/post/7059417952025739300