Насколько мне известно, в Python переменные, объявленные вне функции, могут быть доступны последней, но не могут быть изменены (кроме случаев, когда мы объявляем их глобальными в функции, см. https://www.datacamp.com/community/tutorials/scope-of-variables-python).
Я учусь использовать боке и хочу изменять экземпляры (раскрывающиеся списки, таблицы ...) с помощью обратных вызовов. Основываясь на предыдущем абзаце, обратные вызовы не могут изменять эти экземпляры, если последние не объявлены как глобальные. Но приведенный ниже пример кода работает ...
userList = ['a', 'b', 'c', 'd']
folderList = ['e', 'f', 'g', 'h']
s = MultiSelect(options=userList, size=4, width=1000)
ti = TextInput(placeholder='Enter reference')
def populateDropdown(attr, old, new):
#nonlocal s, ti
if new == 0:
options = userList
else:
options =folderList
s.options = options
ti.callback = CustomJS(args=dict(options=s.options, s=s),code = "s.options =
options.filter(i =>i[0].toLowerCase().includes(cb_obj.value.toLowerCase()));console.info(options);")
usersFoldersChoice = RadioButtonGroup(labels=["Users", "Folders"])
usersFoldersChoice.on_change('active', populateDropdown)
Множественный выбор предварительно заполнен userlist. Есть два переключателя, если щелкнуть «Папки», сработает обратный вызов «populateDropdown». Этот обратный вызов должен повторно заполнить множественный выбор s с помощью folderList, а также обновить обратный вызов, связанный с вводом текста ti. Здесь s и ti изменяются без объявления их глобальными, и это работает, что меня смущает.
Кроме того, если я не понимаю, почему мне нужно обновить обратный вызов, связанный с ti, чтобы учесть изменение s (сначала обратный вызов был напрямую назначен ti во время его объявления, но это не сработало. ..)
Заранее благодарим за любые разъяснения!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Ваша интуиция не совсем верна. Вы не можете назначать для переменных вне функции. То есть эта функция не будет обновлять значение x вне функции:
x = {}
def f():
x = [] # this makes a new local variable
Однако, если объекты вне функции являются изменчивый, т.е. они могут быть изменены «на месте», то нет проблем с их обновлением, вызывая для них методы. Например:"
x = {}
def f():
x['a'] = 10 # this will update the x dict in place
Вот почему обратные вызовы Bokeh могут управлять виджетами или объектами источников данных, определенными вне функций.
Я не совсем понимаю ваш последний вопрос.
Мой последний вопрос означает: я поместил console.info(options) в код обратного вызова JS. Если я помещаю этот код вне populateDropdown, журнал всегда возвращает userList. Мне пришлось поместить его В populateDropdown, чтобы он занял в журнале список папок. Это похоже на то, что обратный вызов JS должен быть «обновлен» вместе с раскрывающимся списком ...
Да, это правильно. Для другого: Может, ошибка? Трудно сказать больше без полного, минимального скрипта для запуска.
Хм, ладно, попробую разобраться. В любом случае спасибо за ответ!
О, я вижу! Таким образом, обратным вызовам Bokeh не нужно объявлять переменные, которые они хотят изменить, как «глобальные», поскольку эти объекты могут быть изменены на месте, верно?