如何在discord.py按钮类中更新变量?计数器无法更新问题
问题原因分析
- 按钮类中读取文件、处理
count的代码写在类的顶层(不在__init__方法内),这段代码只会在Python加载类时执行一次,之后每次创建buttons实例都不会重新运行,因此永远复用第一次读取的问题。 - 类顶层代码每次执行时都会强制把
count设为0,直接覆盖了test命令中累加的count值,导致永远读取文件第0行的问题。 - 全局变量滥用导致状态混乱,
current_question和option1作为全局变量,无法为每个buttons实例提供独立的问题数据。
修复方案
步骤1:预加载所有问题数据
一次性把temp.txt中的所有问题读取到内存,避免重复文件IO操作:
import json import discord # 预加载所有问题到全局列表 all_questions = [] with open("temp.txt", "r") as fp: for line in fp: try: question = json.loads(line) all_questions.append(question) except json.JSONDecodeError: print(f"无效JSON行: {line}") # 初始化计数器 count = 0
步骤2:调整按钮类结构
将问题处理逻辑移到__init__方法内,通过参数接收当前问题,让每个View实例拥有独立的问题数据:
class buttons(discord.ui.View): def __init__(self, current_question): super().__init__() self.current_question = current_question # 动态添加选项按钮(多选项可循环实现) option1 = current_question.get("Option1") self.add_item(discord.ui.Button(label=option1, style=discord.ButtonStyle.blurple, custom_id="op1")) # 按钮回调逻辑 @discord.ui.button(custom_id="op1") async def op1(self, interaction: discord.Interaction, button: discord.ui.Button): # 通过实例属性获取当前问题数据 await interaction.response.send_message(f"你选择了选项1,正确答案:{self.current_question.get('Answer')}") button.disabled = True await interaction.message.edit(view=self)
步骤3:修改test命令逻辑
在命令中根据计数器获取对应问题,创建View时传入问题,并处理计数器循环避免越界:
@bot.command() async def test(ctx): global count # 计数器循环,防止超出问题列表长度 if count >= len(all_questions): count = 0 current_question = all_questions[count] await ctx.send(current_question.get("Question"), view=buttons(current_question)) count += 1
关键修改说明
- 预加载问题列表,提升程序性能,避免重复读取文件。
- 按钮类通过实例属性存储当前问题,彻底摆脱对全局变量的依赖,每个View实例对应独立的问题选项。
- 命令中增加计数器循环逻辑,确保问题可以循环使用,不会因索引越界报错。
内容的提问来源于stack exchange,提问作者potatomotato
相关产品推荐
相关产品推荐

