Discord.py遍历频道消息反应报错,求Async/Await使用指导
问题解决:Discord.py中reaction.users()的异步生成器错误
错误原因
报错TypeError: object async_generator can't be used in 'await' expression是因为Discord.py v2.x版本对reaction.users()的实现做了改动——它不再返回可以用await直接获取的用户列表,而是返回一个async_generator(异步生成器),这类对象不能用await表达式直接处理,必须通过async for来逐个遍历其中的元素。
修正方案
把原来尝试用await获取用户列表的代码,改成用async for遍历reaction.users()的结果,同时修正用户判断的逻辑(原代码中用u != client.user.name是错误的,因为u是User对象,应该直接和client.user对象比较,或者用ID比较,避免用户名重复的问题)。
修改后的完整代码
@client.event async def on_message(message): if message.content == "/react": channel_ids = [12345, 67891, 12341] insert_query = "INSERT INTO lnd_reaction (message_id, emoji, member_name, channel_id, active) VALUES (%s, %s, %s, %s, %s)" for channel_id in channel_ids: # 简化循环写法,无需索引遍历 channel = client.get_channel(channel_id) async for msg in channel.history(limit=None): for reaction in msg.reactions: # 用async for遍历异步生成器获取所有反应用户 async for u in reaction.users(): if u != client.user: # 直接比较User对象,避免用户名重复问题 print(msg.id, reaction, u, msg.channel, 1) insert_values = (msg.id, str(reaction), str(u), msg.channel.id, 1) try: cursor.execute(insert_query, insert_values) cnx.commit() except Exception as e: print("错误信息:") print(e) print("程序退出...") exit()
额外优化点
- 将
for i in range(total)改为直接遍历channel_ids,代码更简洁易读。 - 用户判断从
u != client.user.name改为u != client.user,User对象的唯一性由ID保证,对象比较比用户名比较更可靠。
内容的提问来源于stack exchange,提问作者Jenga
相关产品推荐
相关产品推荐

