如何防止两个相互更新的小部件无限循环?

How to prevent infinite loop with two widgets that update each other?

我正在试验 Jupyter Widgets to see if I can make a better version of this,但显然即使更改不是来自用户,观察处理程序也会触发,因此它创建了一个小部件更改另一个小部件的无限循环。最小示例:

import ipywidgets as widgets

a = widgets.FloatText(description='a:')
b = widgets.FloatText(description='b:')


def on_a_change(change):
    b.value = change['new'] + 1
    
a.observe(on_a_change, names='value')


def on_b_change(change):
    a.value = change['new'] + 1

b.observe(on_b_change, names='value')


display(a)
display(b)

有什么方法可以只触发用户发起的更改吗?换句话说,用户更新一个文本框,然后其他文本框从中更新,但这些更新不会触发更多更新。

不确定我是否理解了这个要求,但如果是“多更新一个”,那么你可以尝试以下

import ipywidgets as widgets

a = widgets.FloatText(description='a:')
b = widgets.FloatText(description='b:')

def update_one(x):
    return x + 1

widgets.link((a, 'value'), (b, 'value'), (update_one, update_one))

display(a)
display(b)

widgets.link 似乎可以解决问题,如果你这样做 widgets.link.__doc__ 你可以看到文档并且它接受第三个参数。

>>> print(widgets.link.__doc__)
Link traits from different objects together so they remain in sync.

    Parameters
    ----------
    source : (object / attribute name) pair
    target : (object / attribute name) pair
    transform: iterable with two callables (optional)
        Data transformation between source and target and target and source.

所以我添加了一个可调用对象的可迭代对象,并使其比您输入的值 return 1 多。

你也可以unobserve一个函数当你改变值的时候,然后再重新设置它。

def on_a_change(change):
    b.unobserve(on_b_change, names='value')
    b.value = change['new'] + 1
    b.observe(on_b_change, names='value')