重用来自不同IPython笔记本的代码

时间:2013-06-06 15:34:05

标签: python ipython ipython-notebook

我正在使用IPython并希望从另一个笔记本中运行功能(不需要在不同的笔记本之间剪切和粘贴它们)。这可能并且相当容易吗?

10 个答案:

答案 0 :(得分:34)

使用以下命令启动笔记本服务器:

ipython notebook --script

也会将笔记本(.ipynb)保存为Python脚本(.py),然后您就可以导入它们了。

或者看一下:http://nbviewer.ipython.org/5491090/包含2个笔记本,一个执行另一个笔记本。

答案 1 :(得分:21)

在IPython 2.0中,您只需%run 'my_shared_code.ipynb'即可在笔记本之间共享代码。请参阅示例http://nbviewer.ipython.org/gist/edrex/9044756

答案 2 :(得分:13)

Ipythons %run magic允许您在笔记本中执行python文件和ipython脚本。我有时使用-i选项,因此它在notebooks命名空间中运行。执行包含%run?的单元格以获取更多信息。

您可以使用ipython --script在每次保存时将笔记本保存为.py个文件,或取消注释c.NotebookManager.save_script=True文件中的行ipython_notebook_config.py以获得相同的效果(使用{ {1}}用于设置 - 在Ubuntu上配置文件位于ipython profile create)。

修改:以下情况属实,但不必要 - 您可以直接~/.config/ipython/ %run个文件。谢谢Eric

如果你在要导入的笔记本中使用ipython magics,我发现你可以将.ipynb文件重命名为.py(一个ipython脚本),但我不得不删除第一行(包含文件编码声明)使其工作。可能有更好的方法!这种方法也可能会混淆细胞魔法(他们都会立即应用)。

答案 3 :(得分:4)

您可以将qtconsole连接到同一个内核。只需在启动时提供:

ipython qtconsole --existing kernel-0300435c-3d07-4bb6-abda-8952e663ddb7.json

在为长字符串启动笔记本后查看输出。

答案 4 :(得分:4)

还有一个“写入和执行”扩展程序,可以让您将单元格的内容写入文件(并替换旧内容 - >更新代码),然后可以将其导入另一个笔记本中。

https://github.com/minrk/ipython_extensions#write-and-execute

在一个笔记本中(两个单元格)

%reload_ext writeandexecute
--
%%writeandexecute -i some_unique_string functions.py
def do_something(txt):
    print(txt)

然后在另一个笔记本中:

from functions import do_something
do_something("hello world")

答案 5 :(得分:2)

是的,你可以“从另一个笔记本上运行功能(不用在不同的笔记本之间剪切和粘贴它们)” - 而且,是的,它很容易做到!

tl; dr:将代码放在python文件(*.py)中的文件系统&让多个笔记本使用相同的代码。 (就这么简单。)

(为什么在笔记本电脑中放入如此多的代码,当我们有完美的代码编辑器和IDE,它们更适合编写和阅读代码?更不用说需要正确的版本控制了!我们是什么?试图实现,并付出多少代价?</rant>

<强>详细信息:

  • 将您的代码放在普通的python文件中,例如my_code/foo.py,添加一个(可能为空)my_code/__init__.py
  • 利用正确版本控制下的代码(例如git) - 注意diff ipynb json文件有多难?
  • 此外,笔记本电脑也受版本控制。原始git日志将难以阅读,但评论可能很有用。 (GitHub / GitLab显示ipython笔记本,顺便说一句。)
  • 将ipynb笔记本中的py源限制为少量的“驱动程序”代码,输出和文档。
  • 如果你想“内联”外部python文件,只需使用(例如)magic %cat my_code/foo.py ...

...如果你想让更高级的内容显示内联源(可选,将以下内容添加到外部可重用的源文件中)......

import IPython
from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import get_lexer_for_filename

filename='my_code/foo.py'
with open(filename) as f: code = f.read()
formatter = HtmlFormatter(linenos='inline')
IPython.display.HTML('<style type="text/css">{}</style>{}'.format(
                formatter.get_style_defs('.highlight'),
                highlight(code, get_lexer_for_filename(filename), formatter)))

您最喜爱的代码编辑器&amp; IDE感谢您的支持。

答案 6 :(得分:1)

我打电话给其他笔记本电脑的笔记本电脑。您甚至可以使用以下技巧将“参数”传递给其他笔记本:

params 字典放在“report_template.ipynb”的第一个单元格中。

params = dict(platform='iOS', 
              start_date='2016-05-01', 
              retention=7)
df = get_data(params ..)
do_analysis(params ..)

在另一个(更高逻辑级别)笔记本中,使用此函数执行它:

def run_notebook(nbfile, **kwargs):
    """
    example:
    run_notebook('report.ipynb', platform='google_play', start_date='2016-06-10')
    """

    def read_notebook(nbfile):
        if not nbfile.endswith('.ipynb'):
            nbfile += '.ipynb'

        with io.open(nbfile) as f:
            nb = nbformat.read(f, as_version=4)
        return nb

    ip = get_ipython()
    gl = ip.ns_table['user_global']
    gl['params'] = None
    arguments_in_original_state = True

    for cell in read_notebook(nbfile).cells:
        if cell.cell_type != 'code':
            continue
        ip.run_cell(cell.source)

        if arguments_in_original_state and type(gl['params']) == dict:
            gl['params'].update(kwargs)
            arguments_in_original_state = False

run_notebook("report_template.ipynb", start_date='2016-09-01')

此命令将执行“report_template”笔记本的每个单元格,并将从第二个单元格开始覆盖 params 字典的相关键 < / p>

答案 7 :(得分:1)

我在笔记本中使用以下功能,我想从源笔记本中加载函数或操作:

import io
import nbformat

def execute_notebook(nbfile):
    with io.open(nbfile, encoding="utf8") as f:
        nb = nbformat.read(f, as_version=4)

    ip = get_ipython()

    for cell in nb.cells:
        if cell.cell_type != 'code':
            continue
        ip.run_cell(cell.source)

使用类似:

execute_notebook(path/to/notebook.ipynb)

答案 8 :(得分:0)

因此,@ MikeMuller的好主意适用于本地笔记本,但不适用于远程笔记本(对吧?)。我不认为有一种方法可以远程调用远程服务器上的单个单元格块或ipynb代码函数,并能够以编程方式将结果返回到调用例程中,除非该代码执行非常特殊的通信结果。

当@Matt提交了与

相同的想法时,我正在写作

ipython <URI_to_Notebook> --script

* .pynb是一个JSON容器,而不是一个实际的python脚本。您可以使用ipython导出带有<。p>的* .py

如果目标* .ipynb位于您无法控制的远程计算机上,则可能需要提取该文件,以便将输出写入本地路径。 (尚未考虑是否可以在远程资源上调用此方法来创建本地输出。)创建此项后,您应该能够导入并运行* .py或其中的各个函数。

@Matt关于用io.open(nbfile)运行另一个* .ipynb文件的简洁例子的问题是nbfile是否可以是远程的?看起来像是一个长镜头,但会很棒...

答案 9 :(得分:0)

以下是两个额外提示:

  1. 您也可以直接从笔记本电脑运行%qtconsole魔法,它会自动连接到笔记本内核。

  2. 查看https://github.com/atiasnir/ipnb

    您可以使用它来导入笔记本文件,就像它们是标准的python模块一样(我是作者:-))。这里的主要限制是它将丢弃魔法单元(因为它根本不使用IPython),否则它应该可以正常工作。