将IPython笔记本保持在版本控制下的好策略是什么?

笔记本格式非常适合版本控制:如果想对笔记本和输出进行版本控制,那么这种方法非常有效。当人们只想对输入进行版本控制,而不包括单元格输出时,就会出现烦恼。“构建产品”),可以是大的二进制blob,特别是电影和情节。特别是,我试图找到一个好的工作流程:

allows me to choose between including or excluding output, prevents me from accidentally committing output if I do not want it, allows me to keep output in my local version, allows me to see when I have changes in the inputs using my version control system (i.e. if I only version control the inputs but my local file has outputs, then I would like to be able to see if the inputs have changed (requiring a commit). Using the version control status command will always register a difference since the local file has outputs.) allows me to update my working notebook (which contains the output) from an updated clean notebook. (update)

如前所述,如果我选择包含输出(例如,在使用nbviewer时,这是可取的),那么一切都没问题。问题是当我不想对输出进行版本控制时。有一些工具和脚本可以剥离笔记本的输出,但我经常遇到以下问题:

I accidentally commit a version with the the output, thereby polluting my repository. I clear output to use version control, but would really rather keep the output in my local copy (sometimes it takes a while to reproduce for example). Some of the scripts that strip output change the format slightly compared to the Cell/All Output/Clear menu option, thereby creating unwanted noise in the diffs. This is resolved by some of the answers. When pulling changes to a clean version of the file, I need to find some way of incorporating those changes in my working notebook without having to rerun everything. (update)

我已经考虑了下面将要讨论的几个选项,但是还没有找到一个好的全面的解决方案。完整的解决方案可能需要对IPython进行一些更改,或者可能依赖于一些简单的外部脚本。我目前使用mercurial,但希望有一个解决方案也能与git一起工作:一个理想的解决方案是版本控制不可知的。

这个问题已经讨论过很多次了,但是从用户的角度来看,还没有明确的解决方案。这个问题的答案应该能提供明确的策略。如果它需要IPython的最新(甚至是开发版)版本或易于安装的扩展,那是没问题的。

更新:我一直在玩我修改过的笔记本版本,它可以选择保存一个.clean版本,每次保存都使用Gregory Crosswhite的建议。这满足了我的大部分约束条件,但留下了以下问题:

This is not yet a standard solution (requires a modification of the ipython source. Is there a way of achieving this behaviour with a simple extension? Needs some sort of on-save hook. A problem I have with the current workflow is pulling changes. These will come in to the .clean file, and then need to be integrated somehow into my working version. (Of course, I can always re-execute the notebook, but this can be a pain, especially if some of the results depend on long calculations, parallel computations, etc.) I do not have a good idea about how to resolve this yet. Perhaps a workflow involving an extension like ipycache might work, but that seems a little too complicated.

笔记

移除(剥离)输出

When the notebook is running, one can use the Cell/All Output/Clear menu option for removing the output. There are some scripts for removing output, such as the script nbstripout.py which remove the output, but does not produce the same output as using the notebook interface. This was eventually included in the ipython/nbconvert repo, but this has been closed stating that the changes are now included in ipython/ipython,but the corresponding functionality seems not to have been included yet. (update) That being said, Gregory Crosswhite's solution shows that this is pretty easy to do, even without invoking ipython/nbconvert, so this approach is probably workable if it can be properly hooked in. (Attaching it to each version control system, however, does not seem like a good idea — this should somehow hook in to the notebook mechanism.)

新闻组

关于版本控制的笔记本格式的思考。

问题

977:笔记本功能请求(打开)。 1280:清除-all保存选项(打开)。(从下面的讨论。) 3295:自动导出的笔记本:只导出显式标记的单元格(关闭)。扩展解决11添加写和执行魔法(合并)。

把请求

1621: clear In[] prompt numbers on "Clear All Output" (Merged). (See also 2519 (Merged).) 1563: clear_output improvements (Merged). 3065: diff-ability of notebooks (Closed). 3291: Add the option to skip output cells when saving. (Closed). This seems extremely relevant, however was closed with the suggestion to use a "clean/smudge" filter. A relevant question what can you use if you want to strip off output before running git diff? seems not to have been answered. 3312: WIP: Notebook save hooks (Closed). 3747: ipynb -> ipynb transformer (Closed). This is rebased in 4175. 4175: nbconvert: Jinjaless exporter base (Merged). 142: Use STDIN in nbstripout if no input is given (Open).


不幸的是,我对Mercurial了解不多,但我可以为您提供一个与Git一起工作的可能解决方案,希望您能够将我的Git命令转换为对应的Mercurial命令。

对于后台,在Git中,add命令将对文件所做的更改存储到暂存区域。完成此操作后,Git将忽略对文件的任何后续更改,除非您告诉它也执行这些更改。因此,下面的脚本,对于每个给定的文件,剥离所有的输出和prompt_number部分,运行剥离的文件,然后恢复原始文件:

注意:如果运行此命令会得到类似ImportError的错误消息:没有名为IPython的模块。Nbformat,然后使用ipython而不是python来运行脚本。

from IPython.nbformat import current
import io
from os import remove, rename
from shutil import copyfile
from subprocess import Popen
from sys import argv

for filename in argv[1:]:
    # Backup the current file
    backup_filename = filename + ".backup"
    copyfile(filename,backup_filename)

    try:
        # Read in the notebook
        with io.open(filename,'r',encoding='utf-8') as f:
            notebook = current.reads(f.read(),format="ipynb")

        # Strip out all of the output and prompt_number sections
        for worksheet in notebook["worksheets"]:
            for cell in worksheet["cells"]:
               cell.outputs = []
               if "prompt_number" in cell:
                    del cell["prompt_number"]

        # Write the stripped file
        with io.open(filename, 'w', encoding='utf-8') as f:
            current.write(notebook,f,format='ipynb')

        # Run git add to stage the non-output changes
        print("git add",filename)
        Popen(["git","add",filename]).wait()

    finally:
        # Restore the original file;  remove is needed in case
        # we are running in windows.
        remove(filename)
        rename(backup_filename,filename)

一旦脚本在您想要提交的文件上运行,只需运行git commit。


这是我的解决方案与git。它允许你像往常一样添加和提交(和diff):这些操作不会改变你的工作树,同时(重新)运行一个笔记本不会改变你的git历史。

虽然这可能适用于其他VSC,但我知道它不能满足您的要求(至少VSC不可知)。不过,它对我来说是完美的,尽管它没有什么特别出色的地方,而且很多人可能已经在使用它了,但我没有通过谷歌找到关于如何实现它的明确说明。所以它可能对其他人有用。

将包含此内容的文件保存在某个位置(对于下面的内容,让我们假设~/bin/ipynb_output_filter.py) (chmod +x ~/bin/ipynb_output_filter.py) 创建文件~/。Gitattributes,包含以下内容 *。ipynb过滤器= dropoutput_ipynb 执行如下命令: Git配置——全局核心。attributesfile ~ / .gitattributes Git配置——global filter.dropoutput_ipynb。干净的~ / bin / ipynb_output_filter.py Git配置——global filter.dropoutput_ipynb。涂抹的猫

完成了!

限制:

it works only with git in git, if you are in branch somebranch and you do git checkout otherbranch; git checkout somebranch, you usually expect the working tree to be unchanged. Here instead you will have lost the output and cells numbering of notebooks whose source differs between the two branches. more in general, the output is not versioned at all, as with Gregory's solution. In order to not just throw it away every time you do anything involving a checkout, the approach could be changed by storing it in separate files (but notice that at the time the above code is run, the commit id is not known!), and possibly versioning them (but notice this would require something more than a git commit notebook_file.ipynb, although it would at least keep git diff notebook_file.ipynb free from base64 garbage). that said, incidentally if you do pull code (i.e. committed by someone else not using this approach) which contains some output, the output is checked out normally. Only the locally produced output is lost.

我的解决方案反映了这样一个事实:我个人不喜欢对生成的东西进行版本控制——注意,涉及输出的合并几乎肯定会使输出或您的生产力无效,或者两者都无效。

编辑:

如果你确实采用了我建议的解决方案——也就是全局的解决方案——你会遇到一些麻烦,比如你想要版本输出的git repo。因此,如果你想禁用特定git存储库的输出过滤,只需在其中创建一个文件.git/info/attributes,使用 **ipynb过滤器=

作为内容。显然,以同样的方式也可以做相反的事情:仅为特定的存储库启用筛选。

代码现在在它自己的git repo中维护 如果上面的指令导致ImportErrors,尝试在脚本路径之前添加"ipython": Git配置——global filter.dropoutput_ipynb。清除ipython ~/bin/ipynb_output_filter.py

编辑:2016年5月(更新于2017年2月):我的脚本有几个替代方案-为了完整性,这里是我知道的列表:nbstripout(其他变体),nbstrip, jq。


我使用一种非常务实的方法;它适用于多个笔记本,在多个侧面。它甚至可以让我四处“转移”笔记本。它既适用于Windows,也适用于Unix/MacOS。 阿尔认为很简单,就是解决上面的问题…

概念

基本上,不要跟踪.ipnyb-files,只跟踪相应的.py-files。 通过使用——script选项启动笔记本服务器,在保存笔记本时自动创建/保存该文件。

这些.py文件包含所有输入;非代码保存为注释,单元格边界也是如此。这些文件可以读取/导入(并拖动)到笔记本服务器以(重新)创建一个笔记本。只有输出消失了;直到它重新运行。

我个人使用mercurial对.py文件进行版本跟踪;并使用普通(命令行)命令进行添加、签入(等等)。大多数其他(D) vc都允许这样做。

现在追溯历史很简单;.py文件很小,文本化,区分起来很简单。有时,我们需要一个克隆文件(只是分支;在那里启动第二个笔记本服务器),或者旧版本(签出并导入到笔记本服务器中),等等。

技巧和窍门

添加*。Ipynb到'。hgignore',所以Mercurial知道它可以忽略这些文件 创建一个(bash)脚本来启动服务器(使用——script选项)并对其进行版本跟踪 保存笔记本会保存.py文件,但不会检入。 这是一个缺点:人们可以忘记这一点 这也是一个特性:可以保存一个笔记本(并在以后继续保存),而无需集群存储库历史记录。

祝愿

如果在笔记本仪表板中有一个签到/添加/等按钮就好了 签出到(例如)file@date+rev.py应该很有帮助 要加上这一点,工作量太大了;也许我会这样做一次。到目前为止,我都是手工做的。


我们有一个合作项目,产品是Jupyter notebook,我们在过去六个月里使用了一种非常有效的方法:我们自动激活保存。py文件,并跟踪。ipynb文件和。py文件。

这样,如果有人想查看/下载最新的笔记本,他们可以通过github或nbviewer来完成,如果有人想查看笔记本代码是如何更改的,他们可以只查看.py文件的更改。

对于Jupyter笔记本服务器,可以通过添加这些行来实现

import os
from subprocess import check_call

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    check_call(['jupyter', 'nbconvert', '--to', 'script', fname], cwd=d)

c.FileContentsManager.post_save_hook = post_save

到jupyter_notebook_config.py文件并重新启动笔记本服务器。

如果你不确定在哪个目录中找到你的jupyter_notebook_config.py文件,你可以输入jupyter——config-dir,如果你没有找到这个文件,你可以输入jupyter notebook——generate-config来创建它。

对于Ipython 3笔记本服务器,可以通过添加这些行来实现

import os
from subprocess import check_call

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    check_call(['ipython', 'nbconvert', '--to', 'script', fname], cwd=d)

c.FileContentsManager.post_save_hook = post_save

到ipython_notebook_config.py文件并重新启动笔记本服务器。这些句子来自github问题的答案@minrk提供和@dror包括他们在他的SO回答以及。

对于Ipython 2笔记本服务器,可以通过使用以下命令启动服务器来完成:

ipython notebook --script

或者加上这条直线

c.FileNotebookManager.save_script = True

到ipython_notebook_config.py文件并重新启动笔记本服务器。

如果您不确定在哪个目录中找到您的ipython_notebook_config.py文件,您可以键入ipython locate profile default,如果您在那里没有找到该文件,您可以键入ipython profile create来创建它。

这是我们在github上使用这种方法的项目:这是一个github上探索笔记本电脑最近变化的例子。

我们对此非常满意。


我做了Albert & Rich所做的——不要给.ipynb文件做版本(因为这些文件可能包含图像,这会变得混乱)。相反,要么总是运行ipython notebook——script,要么放c.FileNotebookManager。在你的配置文件中save_script = True,这样当你保存你的笔记本时,总是会创建一个(可版本的).py文件。

为了重新生成笔记本(在签出一个repo或切换一个分支之后),我将脚本py_file_to_notebook .py放在我存储笔记本的目录中。

现在,签出一个repo之后,只需运行python py_file_to_notebook .py来生成ipynb文件。切换分支后,您可能需要运行python py_file_to_notebook .py -ov来覆盖现有的ipynb文件。

为了安全起见,也可以加上 *。Ipynb到你的。gitignore文件。

编辑:我不再这样做了,因为(A)每次签出分支时,你都必须从py文件中重新生成你的笔记本,(B)在笔记本中有其他东西,如markdown,你会丢失。相反,我使用git过滤器从笔记本中剥离输出。关于如何做到这一点的讨论在这里。


下面是Cyrille rosant为IPython 3.0提供的一个新解决方案,它坚持标记文件,而不是基于json的ipymd文件:

https://github.com/rossant/ipymd


正如前面指出的,——脚本在3.x中已弃用。这种方法可以通过应用后保存钩子来使用。特别地,在ipython_notebook_config.py中添加以下内容:

import os
from subprocess import check_call

def post_save(model, os_path, contents_manager):
    """post-save hook for converting notebooks to .py scripts"""
    if model['type'] != 'notebook':
        return # only do this for notebooks
    d, fname = os.path.split(os_path)
    check_call(['ipython', 'nbconvert', '--to', 'script', fname], cwd=d)

c.FileContentsManager.post_save_hook = post_save

代码取自#8009。


好吧,所以看起来目前最好的解决方案,根据这里的讨论,是使一个git过滤器自动剥离ipynb文件提交的输出。

以下是我让它工作的方法(摘自讨论):

我稍微修改了cfriedline的nbstripout文件,当你不能导入最新的IPython时,会给出一个提示性错误: https://github.com/petered/plato/blob/fb2f4e252f50c79768920d0e47b870a8d799e92b/notebooks/config/strip_notebook_output 并将它添加到我的repo中,比如在。/relative/path/to/strip_notebook_output中

还添加了文件.gitattributes文件到repo的根目录,包含:

*.ipynb filter=stripoutput

并创建了setup_git_filters.sh,其中包含

git config filter.stripoutput.clean "$(git rev-parse --show-toplevel)/relative/path/to/strip_notebook_output" 
git config filter.stripoutput.smudge cat
git config filter.stripoutput.required true

并运行source setup_git_filters.sh。花哨的$(git rev-parse…)事情是找到你的回购在任何(Unix)机器上的本地路径。


接下来是Pietro Battiston编写的优秀脚本,如果您遇到这样的Unicode解析错误:

Traceback (most recent call last):
  File "/Users/kwisatz/bin/ipynb_output_filter.py", line 33, in <module>
write(json_in, sys.stdout, NO_CONVERT)
  File "/Users/kwisatz/anaconda/lib/python2.7/site-packages/IPython/nbformat/__init__.py", line 161, in write
fp.write(s)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2014' in position 11549: ordinal not in range(128)

你可以在脚本开头添加:

reload(sys)
sys.setdefaultencoding('utf8')

我创建了nbstripout,基于MinRKs的gist,它同时支持Git和Mercurial(感谢mforbes)。它既可以在命令行上独立使用,也可以作为过滤器使用,可以通过nbstripout install / nbstripout uninstall轻松(un)安装到当前存储库中。

从PyPI或简单地获得它

pip install nbstripout

(2017-02)

策略

on_commit (): 去掉输出>的名称。Ipynb (nbstripout) 去掉输出> name.clean.ipynb (nbstripout,) 总是nbconvert to python: name.ipynb.py (nbconvert) 始终转换为markdown: name.ipynb.md (nbconvert, ipymd) vcs.configure (): Git difftool, mergetool: nbdiff和nbmerge from nbdime

工具

nbstripout: strip the outputs from a notebook src: https://gist.github.com/minrk/6176788 src: https://github.com/kynan/nbstripout pip install nbstripout; nbstripout install ipynb_output_filter: strip the outputs from a notebook src: https://github.com/toobaz/ipynb_output_filter/blob/master/ipynb_output_filter.py ipymd: convert between {Jupyter, Markdown, O'Reilly Atlas Markdown, OpenDocument, .py} src: https://github.com/rossant/ipymd nbdime: "Tools for diffing and merging of Jupyter notebooks." (2015) src: https://github.com/jupyter/nbdime docs: http://nbdime.readthedocs.io/ nbdiff: compare notebooks in a terminal-friendly way nbdime nbdiff works as a git diff tool: https://nbdime.readthedocs.io/en/latest/#git-integration-quickstart nbmerge: three-way merge of notebooks with automatic conflict resolution nbdime nbmerge works as a git merge tool nbdiff-web: shows you a rich rendered diff of notebooks nbmerge-web: gives you a web-based three-way merge tool for notebooks nbshow: present a single notebook in a terminal-friendly way


我已经构建了一个python包来解决这个问题

https://github.com/brookisme/gitnb

它提供了一个CLI,使用git启发的语法来跟踪/更新/区分git repo中的笔记本。

这里有一个例子

# add a notebook to be tracked
gitnb add SomeNotebook.ipynb

# check the changes before commiting
gitnb diff SomeNotebook.ipynb

# commit your changes (to your git repo)
gitnb commit -am "I fixed a bug"

注意最后一步,我使用“gitnb commit”的地方是提交到你的git repo。它本质上是一个包装

# get the latest changes from your python notebooks
gitnb update

# commit your changes ** this time with the native git commit **
git commit -am "I fixed a bug"

还有更多的方法,并且可以配置为在每个阶段需要或多或少的用户输入,但这是总体思想。


在深入研究之后,我终于在Jupyter文档中找到了这个相对简单的预保存钩子。它剥离单元格输出数据。您必须将其粘贴到jupyter_notebook_config.py文件中(参见下面的说明)。

def scrub_output_pre_save(model, **kwargs):
    """scrub output before saving notebooks"""
    # only run on notebooks
    if model['type'] != 'notebook':
        return
    # only run on nbformat v4
    if model['content']['nbformat'] != 4:
        return

    for cell in model['content']['cells']:
        if cell['cell_type'] != 'code':
            continue
        cell['outputs'] = []
        cell['execution_count'] = None
        # Added by binaryfunt:
        if 'collapsed' in cell['metadata']:
            cell['metadata'].pop('collapsed', 0)

c.FileContentsManager.pre_save_hook = scrub_output_pre_save

Rich Signell的回答是:

如果你不确定在哪个目录中找到你的jupyter_notebook_config.py文件,你可以输入jupyter——config-dir [into命令提示符/终端],如果你在那里找不到这个文件,你可以输入jupyter notebook——generate-config创建它。


下面文章中讨论的想法如何,笔记本的输出应该保存在哪里,理由是生成它可能需要很长时间,而且它很方便,因为GitHub现在可以渲染笔记本。添加了用于导出.py文件的自动保存钩子,用于diffs和.html,以便与不使用笔记本或git的团队成员共享。

https://towardsdatascience.com/version-control-for-jupyter-notebook-3e6cef13392d


你可以使用这个jupyter扩展。它可以让你直接上传你的ipython笔记本到github。

https://github.com/sat28/githubcommit

我还制作了一个视频来演示这些步骤 youtube链接


更新:现在你可以编辑Jupyter笔记本 文件直接在Visual Studio Code。您可以选择编辑 笔记本或转换后的python文件。

我终于找到了一个高效而简单的方法,可以让Jupyter和Git很好地一起工作。我还在第一步,但我已经认为它比所有其他复杂的解决方案要好得多。

Visual Studio Code是微软的一个很酷的开源代码编辑器。它有一个优秀的Python扩展,现在允许你导入一个Jupyter笔记本作为Python代码。现在你也可以直接编辑Jupyter笔记本。

将笔记本导入python文件后,所有代码和标记都将放在一个普通的python文件中,注释中有特殊标记。如下图所示:

你的python文件只有笔记本输入单元格的内容。输出将在拆分窗口中生成。你的笔记本里有纯代码,你只是执行它,它不会改变。没有混合输出与您的代码。没有奇怪的JSON难以理解的格式来分析你的差异。

只是纯粹的python代码,你可以很容易地识别每一个差异。

我甚至不再需要为我的.ipynb文件设置版本了。我可以写上*。Ipynb线在。gitignore。

需要生成一个笔记本来发布或与他人共享?没问题,只需在交互式python窗口中单击导出按钮

如果你直接编辑笔记本,现在有一个图标Convert and save to a python script。

这是Visual Studio Code中一个笔记本的截图:

我只使用了一天,但我终于可以愉快地使用Jupyter和Git了。

注:VSCode的代码完成比Jupyter好得多。


刚刚遇到的“jupytext”看起来像一个完美的解决方案。它从笔记本生成一个.py文件,然后保持两者同步。您可以通过.py文件进行版本控制、差异和合并输入,而不会丢失输出。当你打开笔记本时,它使用.py作为输入单元格,使用.ipynb作为输出单元格。如果你想在git中包含输出,那么你可以添加ipynb。

https://github.com/mwouts/jupytext


与2019年更好的方法相比,上面这些2016年非常流行的答案是不一致的。

有几个选项,最好的答案是Jupytext。

Jupytext

在Jupytext上捕获朝向数据科学的文章

它与版本控制的工作方式是将.py和.ipynb文件放在版本控制中。如果您想要输入差异,请查看.py;如果您想要最新呈现的输出,请查看.ipynb。

值得一提的是:VS studio, nbconvert, nbdime, hydrogen

我认为再多做一些工作,VS studio和/或hydrogen(或类似的)将成为解决这个工作流程的主要参与者。


由于存在如此多的策略和工具来处理笔记本电脑的版本控制,我试图创建一个流程图来选择一个合适的策略(创建于2019年4月)


在删除笔记本的输出数年之后,我试图提出一个更好的解决方案。我现在使用Jupytext,这是我设计的Jupyter Notebook和Jupyter Lab的扩展。

Jupytext可以转换Jupyter笔记本到各种文本格式(脚本,Markdown和R Markdown)。反之。它还提供了将笔记本与这些格式之一配对的选项,并自动同步笔记本的两种表示形式(.ipynb和.md/.py/)。R文件)。

让我来解释一下Jupytext是如何回答上述问题的:

允许我在包含或不包含输出之间进行选择,

。海事/ . py。R文件只包含输入单元格。您应该始终跟踪该文件。只有在希望跟踪输出时,才对.ipynb文件进行版本控制。

防止我不小心提交输出,如果我不想要它,

将 *.ipynb 添加到 .gitignore

允许我保持本地版本的输出,

输出保存在(local) .ipynb文件中

允许我看到当我使用我的版本控制系统在输入中有变化时(即,如果我只控制输入,但我的本地文件有输出,那么我希望能够看到输入是否发生了变化(需要提交)。使用版本控制状态命令将总是注册一个差异,因为本地文件有输出。)

.py/。R或。md文件是你要找的

允许我从更新的干净笔记本更新我的工作笔记本(其中包含输出)。(更新)

获取.py/. xml文件的最新修订版本。R或。md文件,并刷新你的笔记本在Jupyter (Ctrl+R)。您将从文本文件中获得最新的输入单元格,并从.ipynb文件中获得匹配的输出。内核不受影响,这意味着您的局部变量被保留-您可以继续在离开它的地方工作。

我喜欢Jupytext的地方是它的笔记本(以.py/。R或.md文件)可以在您喜欢的IDE中编辑。使用这种方法,重构笔记本变得很容易。一旦你完成了,你只需要在Jupyter刷新笔记本。

如果你想尝试一下:安装Jupytext与pip安装Jupytext并重新启动你的Jupyter笔记本或实验室编辑器。打开要进行版本控制的笔记本,并使用Jupyter notebook中的Jupytext菜单(或Jupyter Lab中的Jupytext命令)将其配对到Markdown文件(或脚本)。保存您的笔记本,您将得到两个文件:原始的.ipynb,加上承诺的笔记本文本表示,这非常适合版本控制!

对于那些可能感兴趣的人:在命令行上也可以使用Jupytext。


现在是2020年4月,Jupyter笔记本版本控制有很多策略和工具。这里是你可以使用的所有工具的快速概述,

nbdime - Nice for local diff'ing and merging of notebooks nbstripout - A git filter to automatically remove notebook outputs before each commit jupytext - Keeps a .py companion file sync'ed to each notebook. You only commit .py files nbconvert - Convert notebooks to a python script or HTML (or both) and commit these alternate file types ReviewNB - Shows notebook diff (along with output) for any commit or pull request on GitHub. One can also write comments on notebook cells to discuss changes (screenshot below).

免责声明:我创建了ReviewNB。


我还将添加到其他人建议的https://nbdev.fast.ai/,这是一个最先进的“文学编程环境,正如Donald Knuth在1983年所设想的那样!”

它也有一些git钩子,可以帮助https://nbdev.fast.ai/#Avoiding-and-handling-git-conflicts和其他命令,如:

nbdev_read_nbs nbdev_clean_nbs nbdev_diff_nbs nbdev_test_nbs

所以你也可以创建你的文档,就像在写一个库,例如:

https://dev.fast.ai/ https://ohmeow.github.io/blurr/ https://rbracco.github.io/fastai2_audio/

除了第一个链接,您还可以在这里看到一个视频nbdev教程。