Discord机器人余额命令报错:用户未入库触发KeyError
解决Discord机器人余额命令KeyError问题
问题根源
直接通过用户ID作为键访问servers.json中的数据时,若该ID未在JSON字典中定义,会触发KeyError,本质是缺少用户存在性校验逻辑。
修改方案
以下两种方式均可避免报错,同时优化用户体验:
方案1:使用dict.get()安全获取数据
get()方法会在键不存在时返回默认值(如None),无需直接访问字典键:
@bot.command(name='баланс') async def balance(ctx, user: discord.User = None): user = user or ctx.author user_id_str = str(user.id) # 读取数据库 with open('servers.json', 'r', encoding='utf-8') as f: data = json.load(f) # 安全获取用户数据,不存在则返回None user_data = data.get(user_id_str) if not user_data: await ctx.send(f"Пользователь {user.mention} не найден в базе данных.") # 可选:自动初始化用户数据 data[user_id_str] = {"balance": 0, "last_daily": 0} with open('servers.json', 'w', encoding='utf-8') as f: json.dump(data, f, indent=4) await ctx.send(f"Баланс {user.mention} инициализирован: 0 монет") return # 用户存在时正常返回余额 await ctx.send(f"Баланс пользователя {user.mention}: {user_data['balance']} монет")
方案2:先判断用户ID是否存在于字典中
通过in关键字提前校验键的存在性,逻辑更直观:
@bot.command(name='баланс') async def balance(ctx, user: discord.User = None): user = user or ctx.author user_id_str = str(user.id) with open('servers.json', 'r', encoding='utf-8') as f: data = json.load(f) # 校验用户是否存在 if user_id_str not in data: await ctx.send(f"Пользователь {user.mention} не зарегистрирован в экономической системе.") # 可选:自动完成注册 data[user_id_str] = {"balance": 0} with open('servers.json', 'w', encoding='utf-8') as f: json.dump(data, f, indent=4) await ctx.send(f"{user.mention} успешно зарегистрирован! Начальный баланс: 0 монет") return # 正常返回余额 await ctx.send(f"Баланс пользователя {user.mention}: {data[user_id_str]['balance']} монет")
补充说明
servers.json的标准结构示例:
{ "123456789012345678": { "balance": 500, "last_daily": 1699999999 }, "987654321098765432": { "balance": 1200, "last_daily": 1700000000 } }
- 操作JSON文件时务必指定
encoding='utf-8',避免俄文字符乱码 - 若机器人用户量较大,建议改用SQLite/PostgreSQL等数据库替代JSON,避免并发写入冲突
内容的提问来源于stack exchange,提问作者nE4eHbKa
相关产品推荐
相关产品推荐

