discord.py中如何写入JSON文件不覆盖原有值、扩展用户intro列表?
修正discord.py自我介绍系统存储时覆盖旧数据的问题
现有代码的核心缺陷
- 每次触发命令都会从零初始化空的
data = {"intros": []}内存结构,完全没有提前读取本地intros.json已存储的内容,写入时自然会把所有旧数据替换成当前收集的单个用户信息 - 代码本身存在语法错误,给列表元素赋值用户信息的部分缺失正确的语法逻辑,现有代码无法跑完完整流程
实现增量存储的调整方案
按照你要求的JSON结构(intros为列表,每个元素是存储单个用户信息的单键字典),调整思路非常直接:
- 命令触发后第一时间读取本地已有的
intros.json内容作为内存操作的基础,只有文件不存在时才初始化空结构 - 收集完用户的4项信息后,把当前用户的信息打包成符合格式的字典,用
append方法追加到intros列表中,不修改已有条目 - 把修改后的完整内存对象写回JSON文件,实现旧数据全保留、仅新增当前用户条目的效果
修正后可直接运行的代码
import json import os from discord.ext import commands # 对应你的Cog类内的命令定义 @commands.command(name="intro") async def create_intro(self, ctx: commands.Context): json_save_path = "./cogs/intros.json" # 初始化默认空数据结构 saved_data = {"intros": []} # 优先加载本地已存储的旧数据 if os.path.exists(json_save_path): with open(json_save_path, "r", encoding="utf-8") as f: saved_data = json.load(f) # 原有收集用户信息的流程,补充频道校验避免误接收其他频道消息 await ctx.send("**Let's create your intro...**") await ctx.send("What's your name?") name_resp = await self.client.wait_for( "message", check=lambda msg: msg.author == ctx.author and msg.channel == ctx.channel ) await ctx.send("How old are you?") age_resp = await self.client.wait_for( "message", check=lambda msg: msg.author == ctx.author and msg.channel == ctx.channel ) await ctx.send("Where are you from?") location_resp = await self.client.wait_for( "message", check=lambda msg: msg.author == ctx.author and msg.channel == ctx.channel ) await ctx.send("What about your interests?") interest_resp = await self.client.wait_for( "message", check=lambda msg: msg.author == ctx.author and msg.channel == ctx.channel ) # 打包当前用户的信息为符合格式的条目 current_user_entry = { str(ctx.author.id): { "name": name_resp.content, "age": age_resp.content, "location": location_resp.content, "interests": interest_resp.content } } # 追加条目而不是覆盖原有列表 saved_data["intros"].append(current_user_entry) # 写回文件,关闭ascii转义保证中文正常显示 with open(json_save_path, "w", encoding="utf-8") as f: json.dump(saved_data, f, indent=4, ensure_ascii=False) await ctx.send("你的自我介绍已成功保存!")
可选优化提示
- 如果需要避免同一用户重复执行命令生成多条重复条目,可以在append前遍历现有
intros列表,匹配到对应用户ID的条目时直接覆盖更新,不需要追加新条目 - 给
wait_for逻辑加上超时判断,避免用户中途不回复导致命令一直挂起
内容的提问来源于stack exchange,提问作者Yeti
相关产品推荐
相关产品推荐

