我正在尝试编写一个Jupyter扩展,用户可以使用IPython magics配置笔记本范围的扩展行为。我计划将配置数据放在JS端,放在Jupyter.notebook.metadata
、"tempvars"
中特定于应用程序的密钥下。为了做到这一点,我需要魔法能够更改....metadata["tempvars"]
中的适当值。
如果我加载Jupyter笔记本
并直接从笔记本单元格使用IPython.display.Javascript
进行元数据更改,则它们将成功应用。
JS控制台:
>> Jupyter.notebook.metadata["tempvars"]["universal"] = false
<- false
Jupyter细胞:
[ ]: from IPython.display import Javascript
[ ]: Javascript("Jupyter.notebook.metadata['tempvars']['universal'] = true")
JS控制台:
>> Jupyter.notebook.metadata["tempvars"]["universal"]
<- true // CHANGED AS EXPECTED
然而,如果我试图从魔法内部做同样的事情,它会不起作用:
根据我的magics定义模块,在更广泛的jupyter_tempvars
包中(请不要介意WIP实现(:
from IPython.core.magic import register_line_magic
def load_ipython_extension(ipython):
@register_line_magic
def tempvars(line):
subcommand, arg = line.strip().split(" ")
if subcommand == "universal":
Javascript(f"Jupyter.notebook.metadata['tempvars']['universal'] = {arg.lower()};")
从一个新加载的笔记本,从JS控制台开始:
>> Jupyter.notebook.metadata["tempvars"]["universal"] = false
<- false
Jupyter细胞:
[ ]: %load_ext jupyter_tempvars
[ ]: %tempvars universal true
JS控制台:
>> Jupyter.notebook.metadata["tempvars"]["universal"]
<- false // DID NOT CHANGE
导致Javascript
调用失败的IPython魔术上下文有什么不同
根据Javascript
对象的IPython文档:
创建一个给定原始数据的Javascript显示对象。
当表达式返回此对象或将其传递给display函数时,它将导致数据显示在前端。
事实证明,JS代码在简单地由表达式返回时的呈现是,而不是的通用行为。特别是,在IPython魔术中,必须将Javascript
实例传递给IPython.display.display()
才能对其进行渲染。
这就是IPython在其自己的内置(和待弃用(%javascript
魔术中所做的。