Python 3.7 Discord Bot货币系统KeyError报错的修复求助
问题根因定位
这个KeyError的触发核心是Python字典嵌套赋值的逻辑和预期不匹配,和JSON文件本身的初始空对象状态没有冲突:
- 从
MoneyBank.json加载全量用户数据到内存字典后,空对象{}结构下不存在任何用户ID对应的顶层键 - 原
open_account函数直接对不存在的用户ID键做嵌套赋值(类似data[用户ID]["wallet"] = 0的写法),Python会先尝试读取这个不存在的顶层键,直接抛出KeyError,根本执行不到后续给wallet设值的步骤
修复方案
1. 调整账户初始化逻辑
替换掉直接嵌套赋值的写法,先校验用户ID键是否存在,不存在就先创建完整的账户结构,再写入余额字段:
import json # 通用的JSON加载方法 def load_bank_data(): with open("MoneyBank.json", "r") as f: return json.load(f) # 改造后的open_account函数 def open_account(user_id): user_key = str(user_id) data = load_bank_data() # 仅当用户键不存在时才初始化新账户 if user_key not in data: data[user_key] = { "wallet": 0, "bank": 0 } # 初始化完成后回写文件,保证数据持久化 with open("MoneyBank.json", "w") as f: json.dump(data, f, indent=2)
2. 调整balance查询命令的执行流程
在查询余额前,先触发账户初始化逻辑,保证所有触发命令的用户都存在合法的账户结构,再读取对应余额做展示:
@bot.command() async def balance(ctx): # 先完成账户初始化,避免首次使用时触发KeyError open_account(ctx.author.id) # 读取最新的账户数据 user_data = load_bank_data()[str(ctx.author.id)] # 后续消息展示逻辑正常编写即可 await ctx.send(f"当前钱包余额:{user_data['wallet']},银行存款:{user_data['bank']}")
3. 适配Python 3.7环境的注意事项
- 所有存储在JSON里的用户ID必须转成字符串类型,因为JSON规范不支持整数类型的键,直接存整数会导致下次读取文件时键类型不匹配,出现查询不到的问题
- 写入JSON文件时加上
indent=2参数,生成的格式化JSON文件方便手动检查内容、定位数据异常 - 开发阶段不要捕获KeyError做静默处理,保留明确的报错信息能更快定位代码逻辑问题
内容的提问来源于stack exchange,提问作者monish Gokulsing
相关产品推荐
相关产品推荐

