控制 IPython 小部件的生命周期
Control lifecycle of IPython widget
我有一个 class,它使用 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)
但是,我还希望此 PeriodicCallback 在屏幕上不再显示 html
时停止。通常我会使用 __del__
或 finalize
或其他东西,但看起来 html
对象可能会保留在笔记本的输出历史记录中(变量如 _10
),所以我的定期回调永远存在。
当可显示元素不再显示时,有什么方法可以得到信号吗?
如您所知,后端(IPython 内核)的小部件由单个对象支持,而在前端(浏览器)它将有一个模型,从零到 N意见。
每次显示小部件时,都会创建一个新视图。自 ipywidgets 7 以来,可以通过将 '_view_count' 特征设置为 0 来跟踪前端(浏览器)上的视图数量,但是,请注意帮助字符串中的内容:
EXPERIMENTAL: The number of views of the model displayed in the frontend. This attribute is experimental and may change or be removed in the future. None signifies that views will not be tracked. Set this to 0 to start tracking view creation/deletion. The default is None, which will make it not track the view count (since for many widgets it will lead to a lot of traffic going around).
假设您在 Jupyter notebook 中:
import ipywidgets
slider = ipywidgets.FloatSlider(value=2, _view_count=0)
assert slider._view_count == 0
对于下一个单元格,您显示它:
slider
在下一个单元格中,您可以检查观看次数是否增加了
assert slider._view_count == 1
由于这个'_view_count'是一个trait,你也可以监听变化
# 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,我在其中制作了一个 'ExpensivePlot' 对象,它将跟踪绘图的 'dirty' 状态,并且 _view_count 只在需要时更新绘图。
PS:最后一个例子当然不是一个非常昂贵的情节,而是我在 vaex when I use the bqplot 中所做的情节的精简版本,更新时间可能超过 1 秒一个情节)。
我有一个 class,它使用 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)
但是,我还希望此 PeriodicCallback 在屏幕上不再显示 html
时停止。通常我会使用 __del__
或 finalize
或其他东西,但看起来 html
对象可能会保留在笔记本的输出历史记录中(变量如 _10
),所以我的定期回调永远存在。
当可显示元素不再显示时,有什么方法可以得到信号吗?
如您所知,后端(IPython 内核)的小部件由单个对象支持,而在前端(浏览器)它将有一个模型,从零到 N意见。
每次显示小部件时,都会创建一个新视图。自 ipywidgets 7 以来,可以通过将 '_view_count' 特征设置为 0 来跟踪前端(浏览器)上的视图数量,但是,请注意帮助字符串中的内容:
EXPERIMENTAL: The number of views of the model displayed in the frontend. This attribute is experimental and may change or be removed in the future. None signifies that views will not be tracked. Set this to 0 to start tracking view creation/deletion. The default is None, which will make it not track the view count (since for many widgets it will lead to a lot of traffic going around).
假设您在 Jupyter notebook 中:
import ipywidgets
slider = ipywidgets.FloatSlider(value=2, _view_count=0)
assert slider._view_count == 0
对于下一个单元格,您显示它:
slider
在下一个单元格中,您可以检查观看次数是否增加了
assert slider._view_count == 1
由于这个'_view_count'是一个trait,你也可以监听变化
# 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,我在其中制作了一个 'ExpensivePlot' 对象,它将跟踪绘图的 'dirty' 状态,并且 _view_count 只在需要时更新绘图。
PS:最后一个例子当然不是一个非常昂贵的情节,而是我在 vaex when I use the bqplot 中所做的情节的精简版本,更新时间可能超过 1 秒一个情节)。