@Micah Kornfield 在问题 cmets 中引用的 cellmagic 答案可能非常适合许多情况。然而,在这个问题中,据说避免重复是可取的。假设 SQL 很大,我们不想多次看到同一个查询。
不幸的是,现在是 2021 年,没有简单的解决方案。在 jupyter notebook 中有两个世界,后端是内核,在我们的例子中运行 python,前端运行 javascript。只有 javascript 才能看到降价单元格。可以让后端和前端相互通信,这些方法通常有点hacky,但无论如何我们都会依赖其中的一些。
我编写了一个脚本,它以两种不同的方式完成我们的工作,这可能会带来相似的结果。我将这些方法称为文件读取方法和 javascript 方法。
首先,请将以下文件markdown.py 保存在与 ipython 相同的文件夹中(我们使用单独的文件,因为您指定您的笔记本最终将进入报告,并且不希望将此脚本与笔记本):
from IPython.display import Javascript
from urllib.parse import unquote
from json import loads as jsonloads
def markread(cellnumber,notebookname=None,callbackvar=None):
try:
if type(cellnumber) is int:# maybe check if (varname in globals()):
if callbackvar is not None and type(callbackvar) is str:
return Javascript("const mdtjs = Jupyter.notebook.get_cells().filter(c=>c.cell_type==\"markdown\")["+str(cellnumber)+"].get_text(); IPython.notebook.kernel.execute(\"mdtp = unquote('\"+encodeURI(mdtjs)+\"');mdtp=mdtp[mdtp.find('\\\\n',mdtp.find('```'))+1:min(mdtp.rfind('\\\\n'),mdtp.rfind('```'))].strip();"+callbackvar+"=mdtp;del mdtp\");")
if notebookname is not None and type (notebookname) is str:
if not notebookname.endswith('.ipynb'):
notebookname += '.ipynb'
with open(notebookname) as f:
j = jsonloads(f.read())
mdts = [''.join(c['source'][1:]).strip().strip('`').strip() for c in j['cells'] if c['cell_type']=='markdown']
return mdts[cellnumber]
except:
return None
return None
现在回到笔记本,要加载脚本,你必须导入它:
from markdown import markread, unquote
使用javascript方法需要取消引用,否则可以跳过。
1。文件读取方式:
用法:
marktext = markread(2, notebookname='mynotebookname')
这里marktext 将从mynotebookname 中的第三个降价单元格中获取值(第三个,因为我们生活在一个零索引的世界中,所以 2 表示第三个;如果您跳过 notebookname 中的“.ipynb”扩展名在这种情况下,它将自动附加)。重要 - 此方法读取写入磁盘上的笔记本文件,而不是事物的热状态。如果您在上次保存后更改了任何内容,则可能会出错。
2。 Javascript方法:
用法:
markread(1, callbackvar='marktext')
在这里,我们将第二个降价单元格的值写入一个名为 marktext 的变量中。 Javascript 方法比较复杂——它是异步的,所以我们必须发送我们想要写入的变量的名称(必须是表示其名称的字符串,而不是变量本身)。重要的是还要知道markread 必须是单元格中的最后一个命令,因为 javascript 调用存在限制。
工作原理
在内部,file read 方法只是读取 json 格式的 notebook 文件,从 'cells' 中选择值并过滤掉那些是 markdown 的。
然而,javascript 方法更复杂。它调用 JS,因为 JS 可以访问包括 markdown 在内的单元格,因此 JS 读取单元格值(来自 Jupyter.notebook.get_cells),过滤 markdown 单元格,调用 python 并发回那些 markdown 单元格 - url 编码。那些编码的单元被解码并分配给callbackvar。在这两种方法中,我做了一些关于修剪单元格值(``` 和空格)的开始和结束可能不正确的假设。
有一些方法可以改进代码,例如让它自动检测文件读取方法的笔记本名称,但它涉及更多黑客,再次依赖 javascript 获取笔记本名称或调用 api端口 8888,但必须处理会话密码。我相信我们的脚本已经涵盖了最重要的部分。如果一种方法不起作用,您可能还会使用另一种方法。