控制IPython小部件的生命周期

时间:2017-10-10 12:59:37

标签: python jupyter-notebook ipywidgets

我有一个使用IPython小部件来渲染丰富输出的类。此输出随时间变化。我通过向IOLoop添加回调定期更改输出来管理它。

class Foo(object):
    def _ipython_display_(self, **kwargs):
        html = HTML("<h2>hello</h2>")

        def f():
            html.value = ...  # TODO: replace with weakrefs to avoid cycle

        from tornado.ioloop import PeriodicCallback
        html._pc = PeriodicCallback(f, 1000)
        html._pc.start()

        return html._ipython_display_(**kwargs)

但是,我也希望在屏幕上不再显示html后停止此PeriodicCallback。通常我会使用__del__finalize或其他东西,但似乎html对象可能会保留在笔记本的输出历史记录中(_10等变量),所以我的定期回调永远存在。

当不再显示可显示元素时,有没有办法获取信号?

1 个答案:

答案 0 :(得分:2)

您可能知道,后端的小部件(IPython内核)由单个对象支持,而在前端(浏览器),它将具有模型,以及0到N个视图。 Widget model

每次显示窗口小部件时,都会创建一个新视图。从ipywidgets 7开始,可以跟踪前端(浏览器)上的视图数量,通过将'_view_count'特征设置为0(但在小部件构造中),请注意帮助字符串的内容:

  

实验:前端显示的模型的视图数。此属性是实验性的,可能会在将来更改或删除。无表示不会跟踪视图。将其设置为0可开始跟踪视图创建/删除。默认值为None,这将使跟踪视图计数(因为对于许多小部件,它将导致大量流量转移)。

假设你在Jupyter笔记本中:

import ipywidgets
slider = ipywidgets.FloatSlider(value=2, _view_count=0)
assert slider._view_count == 0

对于下一个单元格,显示它:

slider

在下一个单元格中,您可以检查视图计数是否已经上升

assert slider._view_count == 1

因为这个&#39; _view_count&#39;是一个特质,你也可以听取改变

# use a output widget to lot lose output
output = ipywidgets.Output()
output
def view_count_changed(change):
    with output:
        print('View count has changes', change)
slider.observe(view_count_changed, '_view_count')

一个更高级的示例笔记本,可能很有用is here,我制作了一个“昂贵的地图”。对象,将跟踪“脏”的对象。绘图的状态,_view_count仅在需要时更新绘图。

PS:最后一个例子当然不是一个非常昂贵的情节,而是当我使用vaex进行绘图时我在bqplot中所做的精简版本,它可以采取&gt; 1秒更新图表。