我想等待异步 jupyter 小部件事件,而单元被阻止执行异步代码(因此,通常是空闲的,等待 I/O,利用%autowait
魔法)。不幸的是,当单元格阻塞时,jupyter notebook 似乎没有发送任何 traitlet 事件。上面的文档通过将回调发送到“后台”来规避这一点,因此它可以在单元格完成执行后做出反应。我想避免这种情况,因为它使对后台任务的推理变得比需要的更难;这恰恰违背了我最喜欢的 python 异步事件循环的原则:trio。有没有办法让它工作?
这是适用于 trio 的 jupyter 文档中的示例(尽管它与 asyncio 以相同的方式失败):
import trio
from IPython.display import display
from ipywidgets import IntSlider, Output
%autoawait trio
async def wait_for_change(widget, attribute):
result = None
evt = trio.Event()
def value_changed(change):
nonlocal result
result = change
evt.set()
widget.observe(value_changed, attribute)
try:
await evt.wait()
finally:
widget.unobserve(value_changed, attribute)
return result
slider = IntSlider()
out = Output()
display(slider)
display(out)
# at this point, the widgets are visible
for i in range(10):
out.append_stdout('did work ' + str(i) + '\n')
# here, the cell blocks thanks to the `%autoawait` above -
# but jupyter fails to forward any events
x = await wait_for_change(slider, 'value')
out.append_stdout('async function continued with value ' + str(x) + '\n')