18

我一直在使用“ipython --script”为每个 ipython 笔记本自动保存一个 .py 文件,这样我就可以使用它将类导入其他笔记本。但这最近停止工作,我收到以下错误消息:

`--script` is deprecated. You can trigger nbconvert via pre- or post-save hooks:
ContentsManager.pre_save_hook
FileContentsManager.post_save_hook
A post-save hook has been registered that calls:
ipython nbconvert --to script [notebook]
which behaves similarly to `--script`.

据我了解,我需要设置一个保存后挂钩,但我不明白如何做到这一点。有人可以解释吗?

4

3 回答 3

22

[根据@mobius 饺子的评论更新]

找到你的配置文件:

Jupyter / ipython >= 4.0

jupyter --config-dir

ipython <4.0

ipython locate profile default

如果你需要一个新的配置:

Jupyter / ipython >= 4.0

jupyter notebook --generate-config

ipython <4.0

ipython profile create

在此目录中,将有一个名为 的文件,将ipython 的 GitHub 问题页面[jupyter | ipython]_notebook_config.py中的以下代码放入该文件中:

import os
from subprocess import check_call

c = get_config()

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

对于 Jupyter,在 check_call 中替换ipythonjupyter

请注意,有一个相应的“预保存”钩子,并且您可以调用任何子进程或在那里运行任何任意代码……如果您想做任何花哨的事情,例如首先检查某些条件、通知 API 使用者或添加git commit 保存的脚本。

干杯,

-t。

于 2015-03-30T16:39:05.690 回答
2

这是另一种不调用新线程的方法(使用check_call)。将以下内容添加到jupyter_notebook_config.py特里斯坦的答案中:

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 `ipython 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)
    py_fname = base + '.py'
    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)

c.FileContentsManager.post_save_hook = script_post_save

免责声明:我很确定我是从某处得到的,但现在找不到。把它放在这里以便将来更容易找到(:

于 2016-11-17T17:08:11.073 回答
0

我刚刚遇到了一个问题,我无权重新启动我的 Jupyter 实例,因此无法应用我想要的保存后挂钩。

因此,我提取了关键部分并可以使用以下命令运行它python manual_post_save_hook.py

from io import open
from re import sub
from os.path import splitext
from nbconvert.exporters.script import ScriptExporter

for nb_path in ['notebook1.ipynb', 'notebook2.ipynb']:
    base, ext = splitext(nb_path)
    script, resources = ScriptExporter().from_filename(nb_path)
    # mine happen to all be in Python so I needn't bother with the full flexibility
    script_fname = base + '.py'
    with open(script_fname, 'w', encoding='utf-8') as f:
        # remove 'In [ ]' commented lines peppered about
        f.write(sub(r'[\n]{2}# In\[[0-9 ]+\]:\s+[\n]{2}', '\n', script))

您可以像使用标准后保存挂钩一样添加自己的花里胡哨,配置是正确的继续方式;分享给其他可能陷入类似困境的人,他们无法让配置编辑生效。

于 2018-12-09T15:46:24.043 回答