discord.py自定义表情投票统计命令IndexError报错求助
解决Discord.py自定义表情投票统计的IndexError问题
嘿,我来帮你搞定这个困扰多日的问题!咱先拆解一下报错的根源:
为啥自定义表情会报错?
你之前用普通表情能正常工作,是因为普通表情是Unicode字符,str(i.emoji)返回的就是那个表情字符,和你用来匹配的变量值能对上。但自定义表情是discord.Emoji对象,当你写str(i.emoji) == favore时,左边是<:Favorevole:123456>这种格式的字符串,右边是discord.Emoji对象,两者根本不可能相等!所以你的列表推导式会返回空列表,取[0]自然就触发IndexError了。
解决方案:正确匹配自定义表情
我们有两种可靠的方式来匹配自定义表情的Reaction:
方式1:直接比较Emoji对象
既然i.emoji对于自定义表情来说本身就是discord.Emoji对象,直接和你通过get_emoji获取的对象比较就行,不用转字符串:
thumbsup = len(await next((i.users().flatten() for i in message.reactions if i.emoji == favore), []))
这里用next()函数配合默认空列表,就算没找到对应表情也不会报错(返回0),比直接取[0]更安全。
方式2:用表情ID匹配(更稳妥)
表情的ID是唯一的,就算重名也不会出错,适合服务器里有重名表情的场景:
thumbsup = len(await next((i.users().flatten() for i in message.reactions if i.emoji.id == favore.id), []))
修改后的完整代码
我把你的代码优化了一下,不仅修复了报错,还加了表情存在性检查,避免get_emoji返回None导致后续加Reaction失败:
@client.command(aliases=["crp"]) @commands.has_permissions(administrator=True) async def conteggio_reazioni_personalizzate(ctx, *, proposta): # 获取自定义表情,同时检查是否存在(假设get_emoji是discord.utils.get的封装) favore = discord.utils.get(ctx.guild.emojis, name="Favorevole") contro = discord.utils.get(ctx.guild.emojis, name="Contrario") flore = discord.utils.get(ctx.guild.emojis, name="Astenuto") # 检查表情是否都存在 missing_emojis = [] if not favore: missing_emojis.append("Favorevole") if not contro: missing_emojis.append("Contrario") if not flore: missing_emojis.append("Astenuto") if missing_emojis: await ctx.send(f"找不到以下自定义表情:{', '.join(missing_emojis)}") return # 发送投票消息并添加表情 message = await ctx.send(proposta) await message.add_reaction(favore) await message.add_reaction(contro) await message.add_reaction(flore) # 等待投票时间 await asyncio.sleep(10) # 重新获取消息(更新Reaction数据) message = await ctx.channel.fetch_message(message.id) # 移除机器人自己的Reaction await message.remove_reaction(favore, client.user) await message.remove_reaction(contro, client.user) await message.remove_reaction(flore, client.user) # 统计投票数,用next()避免空列表报错 thumbsup = len(await next((i.users().flatten() for i in message.reactions if i.emoji == favore), [])) thumbsdown = len(await next((i.users().flatten() for i in message.reactions if i.emoji == contro), [])) neutral = len(await next((i.users().flatten() for i in message.reactions if i.emoji == flore), [])) # 发送结果 await ctx.send(f"{thumbsup} a favore , {thumbsdown} contro e {neutral} astenuti")
额外提示
- 如果你原来的
get_emoji不是discord.utils.get的封装,一定要确保它能根据名字在当前服务器返回正确的discord.Emoji对象,否则还是会出现表情找不到的问题。 - 如果投票时间较长,建议用
discord.ext.tasks替代asyncio.sleep,避免阻塞机器人的其他任务,但短时间投票用sleep完全没问题。
内容的提问来源于stack exchange,提问作者peppewarrior1
相关产品推荐
相关产品推荐

