Discord Py Bot JSON数据写入后重启丢失及数值不符问题求助
问题分析与修复方案
你的Discord机器人出现运行时统计显示正常,但重启后数据丢失,JSON文件数值始终为0的问题,核心原因集中在文件路径、异常处理和逻辑漏洞上,以下是具体分析和修复步骤:
核心问题排查
- 文件路径不明确:使用相对路径
'cup.json'时,机器人的运行工作目录可能与你存放JSON文件的目录不一致,导致保存的文件不是你查看的那个。 - 缺乏异常处理:加载/保存JSON时如果出现错误(如文件损坏、权限不足),代码会直接崩溃或静默失败,你无法及时发现问题。
- 自动发送的"Cup"未被统计:默认Discord.py不会处理机器人自身发送的消息,所以违规后自动发送的"Cup"不会被计入统计(这部分是额外逻辑漏洞,可能导致你对统计数值的误解)。
修复步骤
1. 固定文件路径,避免工作目录问题
修改加载/保存函数,使用绝对路径指定JSON文件位置,确保机器人读写的是正确的文件:
import os import json # 获取当前脚本所在的绝对目录 script_dir = os.path.dirname(os.path.abspath(__file__)) cup_file_path = os.path.join(script_dir, 'cup.json') def load_counters(): # 如果文件不存在,自动初始化默认值 if not os.path.exists(cup_file_path): default_data = {"cup": 0} save_counters(default_data) return default_data # 加载文件并确保键存在 with open(cup_file_path, 'r') as f: counters = json.load(f) if "cup" not in counters: counters["cup"] = 0 save_counters(counters) return counters def save_counters(counters): with open(cup_file_path, 'w') as f: json.dump(counters, f, indent=4) # indent参数让JSON格式更易读
2. 添加异常处理,排查错误
在加载/保存函数中加入异常捕获,方便你定位问题(比如权限不足、文件损坏):
def load_counters(): try: if not os.path.exists(cup_file_path): default_data = {"cup": 0} save_counters(default_data) return default_data with open(cup_file_path, 'r') as f: counters = json.load(f) if "cup" not in counters: counters["cup"] = 0 save_counters(counters) return counters except Exception as e: print(f"加载计数器失败: {str(e)}") return {"cup": 0} def save_counters(counters): try: with open(cup_file_path, 'w') as f: json.dump(counters, f, indent=4) except Exception as e: print(f"保存计数器失败: {str(e)}")
3. 优化消息处理逻辑
调整命令判断顺序,避免无效操作;如果需要统计机器人自动发送的"Cup",手动更新计数器:
@client.event async def on_message(message): # 优先处理!totalcup命令,减少不必要的判断 if message.content == '!totalcup': counters = load_counters() await message.channel.send(f"Cup has been said {counters['cup']} times since Bender reset me.") return # 处理目标频道的消息 target_channel_id = 709551578612498453 if message.channel.id == target_channel_id: # 跳过机器人自身的消息(如果不需要统计自己发的,保留此判断) if message.author == client.user: return if message.content == 'cup': counters = load_counters() counters["cup"] += 1 save_counters(counters) return else: cup_meta = client.get_channel(709984510678269982) cup_channel = client.get_channel(target_channel_id) await cup_meta.send(f'{message.author.mention} has violated the sacred rules of Cup') await message.delete() # 手动统计自动发送的cup(如果需要的话) counters = load_counters() counters["cup"] += 1 save_counters(counters) await cup_channel.send('cup') return
4. 验证修复效果
- 手动发送几次
cup到目标频道,查看cup.json文件,确认数值是否更新。 - 重启机器人,执行
!totalcup命令,确认数值不会丢失。 - 如果控制台打印错误信息,根据提示排查(比如权限问题需要调整文件读写权限)。
内容的提问来源于stack exchange,提问作者whenimbender
相关产品推荐
相关产品推荐

