You need to enable JavaScript to run this app. discord.py中如何写入JSON文件不覆盖原有值、扩展用户intro列表?
优惠活动
大模型
产品
解决方案
定价
更多

discord.py中如何写入JSON文件不覆盖原有值、扩展用户intro列表?

修正discord.py自我介绍系统存储时覆盖旧数据的问题

现有代码的核心缺陷

  • 每次触发命令都会从零初始化空的data = {"intros": []}内存结构,完全没有提前读取本地intros.json已存储的内容,写入时自然会把所有旧数据替换成当前收集的单个用户信息
  • 代码本身存在语法错误,给列表元素赋值用户信息的部分缺失正确的语法逻辑,现有代码无法跑完完整流程

实现增量存储的调整方案

按照你要求的JSON结构(intros为列表,每个元素是存储单个用户信息的单键字典),调整思路非常直接:

  1. 命令触发后第一时间读取本地已有的intros.json内容作为内存操作的基础,只有文件不存在时才初始化空结构
  2. 收集完用户的4项信息后,把当前用户的信息打包成符合格式的字典,用append方法追加到intros列表中,不修改已有条目
  3. 把修改后的完整内存对象写回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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.03 06:06:08