tldr;
Эта проблема не относится к телеграмм-ботам или python-telegram-bot
lib.
Это просто функция языка Python.
Причина этого заключается в том, чточем-то похожим на известные лямбда-функции в понимании списка поведение Python.
Контрольный пример
Рассмотрим эту слегка упрощенную версию вашего скрипта:
items = [
('a', 1),
('b', 2),
('c', 3)
]
handlers = [] # think of dispatcher handlers as a list
for i in range(len(items)):
def dummy_func(): # <--- closure
print(items[i][1])
handlers.append(dummy_func) # somewhat similar to dispatcher.add_handler()
for f in handlers: # let's see the results
f()
Выводит точно такой же результат, как и вы:
3
3
3
Пояснение
Вы получаете те же результаты, потому что вы создаете замыкание , определяя dummy_func
внутри for
цикла и используя items[i][1]
внутри самого функционала.
Проблема в том, что вы, вероятно, не ожидаете, что dummy_func
будет ссылаться на переменную i
только тогда, когда эта конкретная функция фактически выполняется .
И поскольку он выполняется после завершения цикла for
, значение i
является его последним значением в цикле.Таким образом, все ваши функции ссылаются на одно и то же значение i
, которое равно 2
, и items[i][1]
всегда будет 3
в этом случае.
Links
Хорошая статья о области видимости и замыканиях в Python.
GitHub gist о замыканиях.