ipywidget 观察方法每次更改都会调用几次,为什么?
ipywidget observe method called several times for every change, why?
我正在尝试了解 ipywidget 下拉菜单如何与观察方法一起工作,并遇到了这个非常有用的 SO 问题:
那里可以找到很好的解释。
稍微调整一下我创建这个小脚本的答案代码:
w = wd.Dropdown(
options=['Addition', 'Multiplication', 'Subtraction'],
value='Addition',
description='Task:',
)
def on_change(change):
print('method is called when printing this')
if change['type'] == 'change' and change['name'] == 'value':
print("changed to %s" % change.new)
else:
print('chage type is not change it is actually:', change['type'])
print('chage name is not value it is actually:', change['name'])
w.observe(on_change)
display(w)
奇怪的是,当一次更改下拉菜单的值时,打印出来的是这样的:
method is called when printing this
chage type is not change it is actually: change
chage name is not value it is actually: _property_lock
method is called when printing this
chage type is not change it is actually: change
chage name is not value it is actually: label
method is called when printing this
changed to Multiplication
method is called when printing this
chage type is not change it is actually: change
chage name is not value it is actually: index
method is called when printing this
chage type is not change it is actually: change
chage name is not value it is actually: _property_lock
因此菜单下拉列表的一次更改调用了 4 次 observe 方法。
这是为什么?
其次,当 observe 写成这样时,这不会发生:
w.observe(on_change, names='value')
那么输出就是:
method is called when printing this
changed to Multiplication
所以在第二种情况下,该方法被调用一次。
谁能解释一下这是怎么回事?
在
w.observe(on_change)
你告诉小部件每次它的任何属性(我猜实际上是 Trait 属性)发生变化时调用 on_change
函数:这包括 value
(这只是你大部分时间都需要)还有它的所有更多“内部属性”(比如 _property_lock
,大多数时候你不需要)。
此行为记录在 w.observe
文档中:
Signature: w.observe(handler, names=traitlets.All, type='change')
Docstring:
Setup a handler to be called when a trait changes.
This is used to setup dynamic notifications of trait changes.
Parameters
----------
handler : callable
A callable that is called when a trait changes. Its
signature should be ``handler(change)``, where ``change`` is a
dictionary. The change dictionary at least holds a 'type' key.
* ``type``: the type of notification.
Other keys may be passed depending on the value of 'type'. In the
case where type is 'change', we also have the following keys:
* ``owner`` : the HasTraits instance
* ``old`` : the old value of the modified trait attribute
* ``new`` : the new value of the modified trait attribute
* ``name`` : the name of the modified trait attribute.
names : list, str, All
If names is All, the handler will apply to all traits. If a list
of str, handler will apply to all names in the list. If a
str, the handler will apply just to that name.
type : str, All (default: 'change')
The type of notification to filter by. If equal to All, then all
notifications are passed to the observe handler.
names
默认为 traitlets.All
,在这种情况下:If names is All, the handler will apply to all traits
.
因此在定义回调时 names=Value
很重要。
我正在尝试了解 ipywidget 下拉菜单如何与观察方法一起工作,并遇到了这个非常有用的 SO 问题:
那里可以找到很好的解释。
稍微调整一下我创建这个小脚本的答案代码:
w = wd.Dropdown(
options=['Addition', 'Multiplication', 'Subtraction'],
value='Addition',
description='Task:',
)
def on_change(change):
print('method is called when printing this')
if change['type'] == 'change' and change['name'] == 'value':
print("changed to %s" % change.new)
else:
print('chage type is not change it is actually:', change['type'])
print('chage name is not value it is actually:', change['name'])
w.observe(on_change)
display(w)
奇怪的是,当一次更改下拉菜单的值时,打印出来的是这样的:
method is called when printing this
chage type is not change it is actually: change
chage name is not value it is actually: _property_lock
method is called when printing this
chage type is not change it is actually: change
chage name is not value it is actually: label
method is called when printing this
changed to Multiplication
method is called when printing this
chage type is not change it is actually: change
chage name is not value it is actually: index
method is called when printing this
chage type is not change it is actually: change
chage name is not value it is actually: _property_lock
因此菜单下拉列表的一次更改调用了 4 次 observe 方法。
这是为什么?
其次,当 observe 写成这样时,这不会发生:
w.observe(on_change, names='value')
那么输出就是:
method is called when printing this
changed to Multiplication
所以在第二种情况下,该方法被调用一次。
谁能解释一下这是怎么回事?
在
w.observe(on_change)
你告诉小部件每次它的任何属性(我猜实际上是 Trait 属性)发生变化时调用 on_change
函数:这包括 value
(这只是你大部分时间都需要)还有它的所有更多“内部属性”(比如 _property_lock
,大多数时候你不需要)。
此行为记录在 w.observe
文档中:
Signature: w.observe(handler, names=traitlets.All, type='change')
Docstring:
Setup a handler to be called when a trait changes.
This is used to setup dynamic notifications of trait changes.
Parameters
----------
handler : callable
A callable that is called when a trait changes. Its
signature should be ``handler(change)``, where ``change`` is a
dictionary. The change dictionary at least holds a 'type' key.
* ``type``: the type of notification.
Other keys may be passed depending on the value of 'type'. In the
case where type is 'change', we also have the following keys:
* ``owner`` : the HasTraits instance
* ``old`` : the old value of the modified trait attribute
* ``new`` : the new value of the modified trait attribute
* ``name`` : the name of the modified trait attribute.
names : list, str, All
If names is All, the handler will apply to all traits. If a list
of str, handler will apply to all names in the list. If a
str, the handler will apply just to that name.
type : str, All (default: 'change')
The type of notification to filter by. If equal to All, then all
notifications are passed to the observe handler.
names
默认为 traitlets.All
,在这种情况下:If names is All, the handler will apply to all traits
.
因此在定义回调时 names=Value
很重要。