You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Discord.py中JSON文件写入重复对象问题求助

问题解决:JSON文件更新时重复追加对象

问题根源

用r+模式打开文件后,执行json.load(f)读取完内容,文件指针会停在文件末尾。此时直接调用json.dump(data, f),新内容会被追加到原有内容后面,而非覆盖,导致JSON文件出现重复对象、格式失效。

另外原代码存在一处逻辑错误:else分支中直接给data[str(user_id)]["Fireworks"]赋值会触发KeyError——因为该用户ID对应的键不存在,需要先创建字典对象。

解决方案

方案一:拆分读取与写入操作

先以只读模式读取数据,处理完积分逻辑后,再以写入模式打开文件覆盖原有内容:

import json

user_id = msg.author.id
user_name = msg.author.display_name

# 读取现有数据
with open("firework_economy.json", 'r') as f:
    data = json.load(f)

# 处理积分更新逻辑
if str(user_id) in data:
    print("Account already made")                       
    data[str(user_id)]["Fireworks"] += 1
else:                              
    # 先创建用户对应的字典,再赋值积分
    data[str(user_id)] = {"Fireworks": 1}
    await msg.channel.send(f"{msg.author.mention} earned 1 firework!")

# 写入更新后的数据(覆盖原有内容)
with open("firework_economy.json", 'w') as f:
    json.dump(data, f, indent=4)  # indent参数让JSON格式更易读

方案二:重置文件指针并截断内容

在同一次文件打开会话中,读取数据后将指针移回文件开头,截断后续内容再写入:

import json

user_id = msg.author.id
user_name = msg.author.display_name

with open("firework_economy.json", 'r+') as f:
    data = json.load(f)
    
    # 处理积分更新逻辑
    if str(user_id) in data:
        print("Account already made")                       
        data[str(user_id)]["Fireworks"] += 1
    else:                              
        data[str(user_id)] = {"Fireworks": 1}
        await msg.channel.send(f"{msg.author.mention} earned 1 firework!")
    
    # 将文件指针移到开头
    f.seek(0)
    # 截断文件,清空指针后的所有内容
    f.truncate()
    # 写入更新后的数据
    json.dump(data, f, indent=4)

两种方案都能解决重复追加的问题,方案一逻辑更直观,方案二无需重复打开文件,可根据需求选择。

内容的提问来源于stack exchange,提问作者DRags

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:10:20