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

Discord.py按钮投票计数异常、显示itertools.count问题求助

问题现象

基于Discord.py开发建议按钮投票功能时出现两个异常:

  • 点击按钮后,嵌入消息的计数位置未显示预期数字,反而输出<class 'itertools.count'>
  • 控制台打印的计数值始终为1,无法实现点击累加效果

异常效果截图:
嵌入消息计数异常截图

问题根因
  1. 变量作用域错误:你将count、count2定义在按钮回调函数内部,每次点击触发回调时都会重新将变量初始化为0,执行+1后结果自然永远为1,无法跨点击累加。
  2. Embed提前静态生成:你在发送初始消息前就固定写死了embed2的footer内容,此时回调内部的count、count2属于回调局部变量,在外层作用域无法访问,Python自动匹配到全局作用域导入的itertools.count类,最终渲染出类名字符串。
  3. 回调未更新Embed内容:回调中直接传入提前生成的旧embed2对象,即使后续修改了计数值,旧对象里存储的还是初始生成时的内容,不会自动同步更新。
  4. 原代码存在缩进错误、头像属性调用不兼容新版本Discord.py的语法问题。
修复后完整可运行代码
import discord
from discord.ui import Button, View

@client.command()
async def suggest(ctx, *, reason):
    # 计数变量定义在回调外层,在整个命令生命周期内持久存储
    likes = 0
    dislikes = 0
    # 记录已投票用户ID,防止重复刷票,不需要可删除
    voted_user_ids = set()

    # 赞成按钮回调
    async def upvote_callback(interaction):
        nonlocal likes, dislikes
        # 重复投票拦截
        if interaction.user.id in voted_user_ids:
            await interaction.response.send_message("你已经提交过投票了", ephemeral=True)
            return
        voted_user_ids.add(interaction.user.id)
        likes += 1
        # 每次投票后基于最新计数重新生成Embed
        updated_embed = discord.Embed(
            color=ctx.author.color,
            timestamp=ctx.message.created_at
        )
        updated_embed.set_author(
            name=f"{ctx.author}({ctx.author.id})",
            icon_url=ctx.author.avatar.url
        )
        updated_embed.add_field(name='Suggestion:', value=reason)
        updated_embed.set_footer(text=f"Likes: {likes} | Dislikes: {dislikes}")
        await interaction.response.edit_message(embed=updated_embed)

    # 反对按钮回调
    async def downvote_callback(interaction):
        nonlocal likes, dislikes
        if interaction.user.id in voted_user_ids:
            await interaction.response.send_message("你已经提交过投票了", ephemeral=True)
            return
        voted_user_ids.add(interaction.user.id)
        dislikes += 1
        # 每次投票后基于最新计数重新生成Embed
        updated_embed = discord.Embed(
            color=ctx.author.color,
            timestamp=ctx.message.created_at
        )
        updated_embed.set_author(
            name=f"{ctx.author}({ctx.author.id})",
            icon_url=ctx.author.avatar.url
        )
        updated_embed.add_field(name='Suggestion:', value=reason)
        updated_embed.set_footer(text=f"Likes: {likes} | Dislikes: {dislikes}")
        await interaction.response.edit_message(embed=updated_embed)

    # 初始化按钮组件
    up_btn = Button(label="Good Suggestion", style=discord.ButtonStyle.green)
    up_btn.callback = upvote_callback
    down_btn = Button(label="Bad Suggestion", style=discord.ButtonStyle.red)
    down_btn.callback = downvote_callback

    # 初始状态Embed
    init_embed = discord.Embed(
        color=ctx.author.color,
        timestamp=ctx.message.created_at
    )
    init_embed.set_author(
        name=f"{ctx.author}({ctx.author.id})",
        icon_url=ctx.author.avatar.url
    )
    init_embed.add_field(name='Suggestion:', value=reason)
    init_embed.set_footer(text=f"Likes: 0 | Dislikes: 0")

    # 挂载组件发送消息
    view = View()
    view.add_item(up_btn)
    view.add_item(down_btn)
    await ctx.send(embed=init_embed, view=view)
关键修改说明
  • 用nonlocal关键字显式声明回调内使用的likes、dislikes是外层命令作用域的变量,而非回调内部的局部变量,解决每次点击重置计数的问题。
  • 删除提前静态生成的固定Embed,每次投票触发回调时,基于最新的计数值动态生成新的Embed对象,从根源解决作用域污染导致的itertools.count类名显示问题。
  • 修正原代码中第二个回调函数缩进错误、avatar属性调用不兼容v2.x版本Discord.py的问题。
  • 新增简单的防重复投票逻辑,避免同一用户反复点击刷票,不需要可以直接删除相关判断。

内容的提问来源于stack exchange,提问作者Willwell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.16 16:15:41