IPython笔记本从原始文本单元读取字符串

7 投票
2 回答
3989 浏览
提问于 2025-04-28 06:39

我在我的IPython笔记本项目中有一个原始文本单元。

有没有什么方法可以用内置函数或者类似的东西把这个文本提取成字符串呢?

暂无标签

2 个回答

1

由于我没有足够的声望,所以不能评论,我就把Graham Klyne的回答更新一下,发在这里,以防其他人看到这个问题时能有所帮助。(到目前为止,Ipython还没有更新的文档)

  1. 使用nbformat,而不是Ipython.nbformat.current。
  2. 工作表的属性已经没有了,所以直接使用单元格。

我有一个更新后代码的示例,大家可以看看:https://github.com/ldiary/marigoso/blob/master/marigoso/notebook_import.py

7

我(可能不太满意的)回答分为两部分。这是基于我个人对iPython结构的研究,可能我错过了一些更直接回答问题的内容。

当前会话

在当前会话中输入的代码单元的原始文本可以通过列表In在笔记本中访问。

所以,当前单元的原始文本可以通过以下表达式在单元内返回:

In[len(In)-1]

例如,评估一个包含以下代码的单元:

print "hello world"
three = 1+2
In[len(In)-1]

会得到对应的Out[]值:

u'print "hello world"\nthree = 1+2\nIn[len(In)-1]'

因此,在一个活跃的笔记本会话中,你可以通过In[n]访问单元的原始文本,其中n是所需单元的显示索引。

但是,如果该单元是在之前的笔记本会话中输入的,而该会话已经关闭并重新打开,那么这个方法就不再有效。此外,似乎只有代码单元包含在In数组中。

另外,这对非代码单元也不适用,所以对于原始文本单元也无法使用。

来自已保存笔记本会话的单元

在我的研究中,我发现获取之前会话的原始文本的唯一方法是读取原始的笔记本文件。有一个文档页面导入IPython笔记本作为模块,描述了如何做到这一点。关键代码在In[4]中:

    # load the notebook object
    with io.open(path, 'r', encoding='utf-8') as f:
        nb = current.read(f, 'json')

其中current是文档中描述的API的一个实例,链接在模块:nbformat.current

返回的笔记本对象作为嵌套的字典和列表结构访问,例如:

    for cell in nb.worksheets[0].cells:
        ...

这样列出的cell对象有两个关键字段,跟这个问题相关:

  1. cell.cell_type是单元的类型(“代码”、“markdown”、“原始”等)。

  2. cell.input是单元的原始文本内容,以字符串列表的形式呈现,每行文本对应一个条目。

通过查看构成已保存的iPython笔记本的JSON数据,可以看到很多内容。

除了笔记本中的“提示编号”字段似乎在每次重新评估时都会变化外,我找不到创建一个稳定的笔记本单元引用的方法。

结论

我没有找到一个简单的答案来回应最初的问题。我找到的内容在上面已经涵盖了。由于不知道最初问题背后的动机,我无法判断这是否足够。

我想找的,但未能识别的是一种可以在笔记本内部使用的引用当前笔记本的方法(例如,通过像get_ipython()这样的函数)。这并不意味着它不存在。

我回答中缺失的另一个部分是任何稳定的方式来引用特定单元。(例如,查看笔记本文件格式,原始文本单元仅由单元类型(“原始”)和原始文本本身组成,尽管似乎单元元数据也可能被包含在内。)这表明直接引用单元的唯一方法是通过它在笔记本中的位置,但在编辑笔记本时,这个位置可能会发生变化。

(作为牛津参与http://aaronswartzhackathon.org的一部分进行研究和回答)

撰写回答