discord.py经验系统等级命令报错KeyError:10,求解决方案
问题排查与解决
错误原因分析
你的代码存在多处逻辑错误,直接引发了KeyError: 10及功能失效:
- 循环变量误用:用
for ctx.id in data会把JSON里的用户ID覆盖命令调用者的ctx.id,完全没必要复用这个变量,应该用独立变量(比如user_id)遍历数据键。 - 数据存储逻辑失效:
model变量在循环中被反复重写,最终只保留最后一个用户的数据,根本没法用来排序所有用户。 - 排序逻辑完全错误:
sorted(users, key=model[exp].__getitem__)里,exp是数值类型的经验值,而model的键是字符串"user"和"exp",用数值当键必然触发KeyError;同时这个写法根本无法关联所有用户的经验值,排序逻辑不成立。
修正后的代码
import json from discord.ext import commands @bot.command() async def rank(ctx): # 读取用户数据文件 with open("users.json", "r") as f: data = json.load(f) # 收集所有用户的(经验值, 用户名)元组,用于排序 user_exp_list = [] for user_id in data: user_info = data[user_id] user_exp_list.append( (user_info["experience"], user_info["user"]) ) # 按经验值降序排序(reverse=True表示从高到低) sorted_users = sorted(user_exp_list, key=lambda x: x[0], reverse=True) # 提取排序后的用户名列表(需要带经验值的话直接用sorted_users即可) ranked_usernames = [user[1] for user in sorted_users] print(ranked_usernames) # 也可以直接在频道发送排名结果,比如: # rank_text = "经验排行榜:\n" + "\n".join([f"{i+1}. {name}" for i, name in enumerate(ranked_usernames)]) # await ctx.send(rank_text)
额外说明
- JSON中的用户ID是字符串类型,直接遍历
data的键即可获取,无需额外格式转换。 - 用元组存储经验值和用户名,排序时通过
lambda x: x[0]指定按经验值排序,逻辑清晰且高效。 - 如果需要显示排名序号、经验值等更多信息,直接遍历
sorted_users生成格式化内容即可。
内容的提问来源于stack exchange,提问作者C1n0x
相关产品推荐
相关产品推荐

