discord.py等级系统set_xp_addition命令JSON文件截断问题求助
Discord等级系统set_xp_addition命令JSON文件截断问题修复
问题根源分析
你的代码存在3个核心问题导致JSON文件被截断:
- 重复加载JSON数据:命令开头已加载一次数据,但后续分支又重复打开文件重新加载,不仅冗余,还可能引发竞态条件(两次加载间文件被其他操作修改),导致写入数据异常甚至文件截断。
- 逻辑判断混乱:
if xp:会将xp=0判定为False,导致后续if xp ==0的分支永远不会执行,逻辑完全失效。 - 文件模式使用不当:
w+模式打开文件时会先清空内容,若写入过程中出现异常(如消息发送延迟),会直接导致文件被截断为空。
修复后代码
@levelmds.command(name="set_xp_addition", description="Choose how many XP you want to give to your members. Set 0 or blank to go to the default. (4)") async def setxpaddition(interaction: discord.Interaction, xp: int = 0): # 仅加载一次JSON数据,避免重复IO操作 try: with open("database\\wae.json", encoding="utf-8") as f: data = json.load(f) except FileNotFoundError: await interaction.response.send_message(":x: 数据库文件不存在,请先初始化等级系统。") return except json.JSONDecodeError: await interaction.response.send_message(":x: 数据库文件损坏,请修复后重试。") return guild_id = str(interaction.guild.id) # 检查服务器配置是否存在 if guild_id not in data: await interaction.response.send_message(f":x: {interaction.guild.name}的配置未初始化,请先启用等级系统。") return # 管理员权限校验 if not interaction.user.guild_permissions.administrator: await interaction.response.send_message(f":x: Only administrators of {interaction.guild.name} can execute this command.") return # 处理XP设置逻辑:0或空值设为默认4,否则设为指定值 target_xp = 4 if xp == 0 else xp data[guild_id]['xpaddition'] = target_xp # 写入修改,使用w模式替代w+,确保写入完成后再发送消息 with open("database\\wae.json", "w", encoding="utf-8") as fa: json.dump(data, fa, indent=2) # indent参数让JSON格式更易读,可选 # 发送结果通知 if target_xp == 4: await interaction.response.send_message("✅ Successfully set XP addition to the default (4)") else: await interaction.response.send_message(f"✅ Successfully changed XP addition to **{target_xp}.**")
关键优化点
- 移除重复文件操作:全程仅加载一次JSON数据,修改后一次性写入,彻底避免竞态条件和冗余IO。
- 修正逻辑判断:直接通过
xp ==0判定是否使用默认值,解决原逻辑的分支错误。 - 优化文件模式:使用
"w"模式替代"w+",专注于写入操作,降低异常导致的文件截断风险;同时显式指定编码,确保特殊字符正常保存。 - 增加异常处理:捕获文件不存在、JSON格式错误等异常,避免程序崩溃并给出明确提示。
内容的提问来源于stack exchange,提问作者As2Bax
相关产品推荐
相关产品推荐

