自动将 jupyter 笔记本转换为 .py

mon*_*ern 6 python bash automation ipython jupyter-notebook

我知道对此有一些疑问,但我还没有发现任何足够可靠的东西。

目前我正在从终端使用一个创建 .py 的命令,然后将它们移动到另一个文件夹:

jupyter nbconvert --to script '/folder/notebooks/notebook.ipynb' &&  \
mv ./folder/notebooks/*.py ./folder/python_scripts && \
Run Code Online (Sandbox Code Playgroud)

然后,工作流程是在笔记本中编码,检查git status自上次提交以来发生的更改,创建可能大量的nbconvert命令,然后将它们全部移动。

我想使用类似于此答案中!jupyter nbconvert --to script找到的内容,但没有出现在 .py 本身中的创建 python 文件的单元格。

因为如果出现该行,我的代码将永远无法正常工作。

那么,有没有一个正确的方法来处理这个问题呢?一种可以自动化的方式,而不是手动复制文件名、创建命令、执行然后重新启动。

53R*_*3RT 5

另一种方法是使用Jupytext作为 jupyter 安装的扩展(可以轻松 pip 安装)。

Jupytext 描述(参见 github 页面)

您是否一直希望 Jupyter 笔记本是纯文本文档?希望您可以在您最喜欢的 IDE 中编辑它们?在进行版本控制时获得清晰且有意义的差异?那么... Jupytext 很可能就是您正在寻找的工具!

它将保持配对笔记本与文件同步.py。然后,您只需移动.py文件或 gitignore 笔记本即可作为可能的工作流程。


mon*_*ern 0

是我发现的最接近我的想法的,但我还没有尝试和实现它:

   # A post-save hook to make a script equivalent whenever the notebook is saved (replacing the --script option in older versions of the notebook):

import io
import os
from notebook.utils import to_api_path

_script_exporter = None

def script_post_save(model, os_path, contents_manager, **kwargs):
    """convert notebooks to Python script after save with nbconvert

    replaces `jupyter notebook --script`
    """
    from nbconvert.exporters.script import ScriptExporter

    if model['type'] != 'notebook':
        return

    global _script_exporter

    if _script_exporter is None:
        _script_exporter = ScriptExporter(parent=contents_manager)

    log = contents_manager.log

    base, ext = os.path.splitext(os_path)
    script, resources = _script_exporter.from_filename(os_path)
    script_fname = base + resources.get('output_extension', '.txt')
    log.info("Saving script /%s", to_api_path(script_fname, contents_manager.root_dir))

    with io.open(script_fname, 'w', encoding='utf-8') as f:
        f.write(script)
Run Code Online (Sandbox Code Playgroud)

c.FileContentsManager.post_save_hook = script_post_save

另外,看起来对 github 上的一些用户有用,所以我把它放在这里供参考:

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)
Run Code Online (Sandbox Code Playgroud)