Jupyter中的非阻塞单元执行

时间:2019-04-03 20:34:03

标签: jupyter-notebook ipython ipywidgets

在具有ipython内核的Jupyter中,是否存在以非阻塞方式执行单元的规范方法?

理想情况下,我希望能够运行一个单元格

%%background
time.sleep(10)
print("hello")

这样我就可以开始编辑和运行下一个单元格,并在10秒内看到“ hello”出现在原始单元格的输出中。


我尝试了两种方法,但都不满意。

(1)手动创建线程:

def foo():
    time.sleep(10)
    print("hello")
threading.Thread(target=foo).start()

问题在于,“ hello”会在10秒内处于活动状态的单元格中打印出来,而不必在启动线程的单元格中打印出来。

(2)使用ipywidget.Output小部件。

def foo(out):
    time.sleep(10)
    out.append_stdout("hello")
out = ipywidgets.Output()
display(out)
threading.Thread(target=foo,args=(out,)).start()

这可行,但是当我想更新输出时会出现问题(例如监视内存消耗之类的东西):

def foo(out):
    while True:
        time.sleep(1)
        out.clear_output()
        out.append_stdout(str(datetime.datetime.now()))
out = ipywidgets.Output()
display(out)
threading.Thread(target=foo,args=(out,)).start()

现在输出的大小在0到1行之间不断切换,这会导致整个笔记本闪烁。

在对wait=True的调用中,clear_output应该可以解决。 las,对我来说,它导致输出永不显示任何内容。

本来我可能会问这个问题,具体来说这似乎是个错误,但是我想知道是否存在另一种不需要我手动完成所有工作的解决方案。

1 个答案:

答案 0 :(得分:0)

我在绘制到输出时遇到了类似的问题,看起来您已经按照ipywidgets文档中有关异步输出小部件的示例进行了操作。

我发现有时另一种有用的方法(特别是如果您知道所需输出的大小的话)是在创建输出小部件时固定其高度。

out = ipywidgets.Output(layout=ipywidgets.Layout(height='25px'))