从Jupyter Comm设置全局变量

时间:2018-04-10 15:02:20

标签: javascript python d3.js jupyter-notebook

我试图在Jupyter笔记本中的javascript中访问python单元格中的数据。我正在使用Jupyter的Comm功能。设置以下HTML单元格以提供d3js以及d3可以选择的<div>

%%HTML
<div class="anchor"></div>
<script>
    requirejs.config({
        paths: {
            d3: 'https://d3js.org/d3.v5'
        }
    });

    require(['d3'], function(d3) {
        window.d3 = d3;
    });
</script>

接下来我运行一个python单元来发送通信数据。

def target_func(comm, msg):
    comm.send({'abc': 123})

get_ipython().kernel.comm_manager.register_target('data', target_func)

最后,我运行一个javascript单元格来显示上面python单元格中的数据。我也正在登录控制台以确保数据确实存在(并且确实存在)。

%%javascript
var comm = Jupyter.notebook.kernel.comm_manager.new_comm('data');
var temp
comm.on_msg(function(msg) {
    console.log(msg.content.data);
    temp = msg
});

d3.select(".anchor").append("span").text(temp);

问题:我无法从函数范围之外的comm消息中获取数据。在上面的示例中,当d3使用文本附加范围时,该变量temp未定义。

如何从comm函数的范围中获取comm消息中的数据?

1 个答案:

答案 0 :(得分:1)

如果您在<{1}}回调中调用d3.select(".anchor").append("span").text(temp); ,该怎么办?

e.g:

on_msg

我认为你的错误是你在定义附加 %%javascript var comm = Jupyter.notebook.kernel.comm_manager.new_comm('data'); var temp comm.on_msg(function(msg) { console.log(msg.content.data); temp = msg d3.select(".anchor").append("span").text(temp); }); 回调之后立即调用d3。定义和附加回调的行为不会使其立即运行。它只在从内核收到消息时运行,而 JavaScript运行时碰巧可以自由运行它。

所以真正发生的事情是你定义并附加了回调,然后执行了d3的东西,然后JavaScript引擎完成了对块的评估。只有在完成对块的评估之后,引擎才能自由地接受来自内核的消息并触发回调,这时为时已晚,因为你已经调用了d3的东西。