python - Python Telegram bot 从列表中添加处理程序
问题描述
我在运行时添加命令处理程序时遇到问题,这是一个示例:
from telegram.ext import Updater, CommandHandler
updater = Updater(token)
items = [
('a', 1),
('b', 2),
('c', 3)
]
for i in range(len(items)):
def dummy_func(bot, update):
print(items[i][1])
updater.dispatcher.add_handler(
CommandHandler(items[i][0], dummy_func)
)
updater.start_polling()
例如,我希望在我的控制台中/a
打印1
,而是3
为 a、b 或 c 打印。我想也许该函数每次都存储在内存中的同一个位置,并尝试将回调存储在一个列表中,但它没有帮助。
关于如何做到这一点的任何想法?
解决方案
tldr;
此问题不属于电报机器人或python-telegram-bot
lib。
这只是 Python 语言的一个特性。
这背后的原因有点类似于列表理解python 行为中著名的 lambda 函数。
测试用例
考虑这个稍微简化的脚本版本:
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
解释
您会得到相同的结果,因为您通过定义内部循环并在 func 本身内部使用来创建闭包。dummy_func
for
items[i][1]
问题是您可能不希望仅在实际执行此特定函数时dummy_func
才会引用变量。i
并且由于它是在for
循环结束后执行的,所以它的值i
是它在循环中的最后一个值。因此,您的所有函数都引用 的相同值i
,即2
,并且在这种情况下items[i][1]
将始终3
如此。
链接
推荐阅读
- bash - 7zip - 不要添加到现有存档,仅创建新存档
- python - 在python中使用selenium在输入标签中填写用户名和密码
- reactjs - 嵌套路由的 React Router 整页
- r - hasGroups 中的错误:缺少参数“数据集”,在具有模块的应用程序中没有默认值
- python - 多元线性回归 - 为什么我的截距每次都如此不同?
- android - 如何访问 kivy android 应用程序上的配置文件?
- python - 你如何存储一些 python 代码的结果以用于另一个计算?
- python - 将 Python struct.pack 转换为 C#
- c# - 为什么 TCP 端点断开连接会在另一个端点上抛出一堆 0 字节?
- reactjs - TypeError:无法在 React 中将未定义转换为对象