You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 23:27:53