Discord.py按钮投票计数异常、显示itertools.count问题求助
问题现象
基于Discord.py开发建议按钮投票功能时出现两个异常:
- 点击按钮后,嵌入消息的计数位置未显示预期数字,反而输出
<class 'itertools.count'> - 控制台打印的计数值始终为1,无法实现点击累加效果
异常效果截图:
问题根因
- 变量作用域错误:你将
count、count2定义在按钮回调函数内部,每次点击触发回调时都会重新将变量初始化为0,执行+1后结果自然永远为1,无法跨点击累加。 - Embed提前静态生成:你在发送初始消息前就固定写死了
embed2的footer内容,此时回调内部的count、count2属于回调局部变量,在外层作用域无法访问,Python自动匹配到全局作用域导入的itertools.count类,最终渲染出类名字符串。 - 回调未更新Embed内容:回调中直接传入提前生成的旧
embed2对象,即使后续修改了计数值,旧对象里存储的还是初始生成时的内容,不会自动同步更新。 - 原代码存在缩进错误、头像属性调用不兼容新版本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
相关产品推荐
相关产品推荐

