Функция обратного вызова в боке обычно имеет три аргумента: attr
, old
и new
, как показано в этом примере в документации
def my_text_input_handler(attr, old, new):
print("Previous label: " + old)
print("Updated label: " + new)
text_input = TextInput(value = "default", title = "Label:")
text_input.on_change("value", my_text_input_handler)
Мои вопросы:
attr
не используется внутри тела функции
my_text_input_handler
? Что (attr
) это на самом деле?"value"
в методе
text_input.on_change("value"...)
?Спасибо.
Из документов:
Все виджеты имеют метод .on_change, который принимает имя атрибута и один или несколько обработчиков событий в качестве параметров. Ожидается, что эти обработчики будут иметь сигнатуру функции (attr, old, new), где attr относится к имени измененного атрибута, а old и new относятся к предыдущим и обновленным значениям атрибута.
attr
не используется внутри тела функции my_text_input_handler, потому что она не полагается на данные и ничего с ними не делает. Все обратные вызовы имеют одну и ту же подпись, func(attr, old, new)
, и этот пример просто ничего не делает с attr
. Краткий ответ, почему он не используется: нет особой причины...Вы можете легко переписать его так:
def my_text_input_handler(attr, old, new):
print("attr: " + attr)
print("Previous label: " + old)
print("Updated label: " + new)
attr
соответствует «значению» в text_input.on_change("value", my_text_input_handler)
.
text_input.on_change
, — это имя атрибута text_input
, который вы просматриваете. Таким образом, каждый раз, когда атрибут «значение» изменяется у объекта text_input
, вызывается функция обратного вызова (my_text_input_handler
) с именем атрибута («значение») и старым и новым значениями.Взгляните на этот пример HTML/Javascript, чтобы лучше понять, что он делает: https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onchange2
Вот пример, который поможет проиллюстрировать, что делает обратный вызов. Сохраните этот код как «demo.py», запустите его через bokeh serve demo.py
и проверьте, как он работает.
'''
Use the ``bokeh serve`` command to run the example by executing:
bokeh serve demo.py
at your command prompt. Then navigate to the URL
http://localhost:5006/demo
in your browser.
'''
from bokeh.io import curdoc
from bokeh.models import TextInput
def my_text_input_handler(attr, old, new):
print("attr: " + attr)
print("Previous label: " + old)
print("Updated label: " + new)
text_input = TextInput(value = "default", title = "Label:")
text_input.on_change("value", my_text_input_handler)
curdoc().add_root(text_input)
Ваш исходный код действительно должен печатать:
Previous label: default
Updated label: test
Да, attr — это сокращение от атрибута или имени атрибута. Это прямо соответствует «значению» в этом вызове: text_input.on_change("value", my_text_input_handler)
. Я добавил наглядный пример в свой исходный пост.
Спасибо, Капочи. Это был именно тот код, который я тестировал до того, как вы добавили пример. Но, как я уже сказал, при изменении значения «по умолчанию» на «тест» в текстовом поле ничего не распечатывалось!
Вы должны щелкнуть за пределами текстового поля, чтобы зарегистрировать его. Я только что попробовал это с кодом, который я разместил выше, и он работает.
Ах, я думал, что предложения будут напечатаны в Интернете, где было текстовое поле, не знал, что они отображаются в подсказке анаконды! Спасибо. Тем не менее, странно указать аргумент (attr
), но не использовать его в функции!
Bokeh вызывает предоставленный обратный вызов с тремя аргументами, поэтому ваш обработчик обратного вызова должен определить три аргумента (здесь они называются attr, old и new). В качестве альтернативы вы можете использовать лямбда, если вам действительно не нравится один используемый аргумент: text_input.on_change("value", lambda attr, old, new: my_handler(old, new))
но, конечно, теперь у вас есть лямбда-функция, которая не использует все свои аргументы.
Спасибо за объяснение, Капочи. Я все еще смущен
attr
. это сокращение от атрибута? Если да, то связано ли это с атрибутомtext_input
, упомянутым в пункте 2 вашего ответа? Не могли бы вы привести пример (с фактическими значениями) при объяснении этих концепций, чтобы я мог следовать? При запуске кода (с предложенной вами функцией, которая имелаprint("attr: " + attr)
), он отображал текстовое поле со значением («по умолчанию»). Затем я изменил это значение на «тест», но ничего не распечатывалось (так как я хотел увидеть, что такоеattr
). Почему это?