Python Telegram 机器人从列表中添加处理程序
Python Telegram bot adding handlers from list
我在 运行 上添加命令处理程序时遇到问题,这是一个示例:
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
库。
它只是 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
说明
你会得到相同的结果,因为你通过在 for
循环内定义 dummy_func
并在 func 本身内使用 items[i][1]
创建了一个 闭包 。
问题是您可能不希望 dummy_func
仅在实际执行此特定函数 时才会引用变量 i
。
并且由于它是在for
循环结束后执行的,所以i
的值是它在循环中的最后一个值。因此,您的所有函数都引用 i
的相同值,即 2
,并且 items[i][1]
在这种情况下将始终是 3
。
链接
Nice article 关于 Python 中的作用域和闭包。
GitHub gist 关于关闭。
我在 运行 上添加命令处理程序时遇到问题,这是一个示例:
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
库。
它只是 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
说明
你会得到相同的结果,因为你通过在 for
循环内定义 dummy_func
并在 func 本身内使用 items[i][1]
创建了一个 闭包 。
问题是您可能不希望 dummy_func
仅在实际执行此特定函数 时才会引用变量 i
。
并且由于它是在for
循环结束后执行的,所以i
的值是它在循环中的最后一个值。因此,您的所有函数都引用 i
的相同值,即 2
,并且 items[i][1]
在这种情况下将始终是 3
。
链接
Nice article 关于 Python 中的作用域和闭包。
GitHub gist 关于关闭。