discord.py等级系统服务器专属排行榜实现故障求助
问题原因
你原来的排行榜代码存在3个核心错误:
- 直接对
data.items()排序,data的一级键是服务器ID,不是用户ID,排序逻辑完全不符合存储结构 - 读取经验值时调用了不存在的
xp字段,你存储的经验字段名为experience,会触发KeyError - 没有按当前触发命令的服务器过滤数据,自然无法实现分服务器的专属排行榜
修复后的排行榜代码
@client.command(aliases = ['lb', '排行榜']) async def leaderboard(ctx, show_top: int = 10): # 限制最多显示前20名,避免embed内容过长 show_top = min(show_top, 20) with open('level.json', 'r') as f: data = json.load(f) # 先取当前服务器的所有用户数据 guild_id = str(ctx.guild.id) if guild_id not in data: await ctx.send("当前服务器还没有等级数据") return guild_users = data[guild_id] # 按等级降序、经验降序排序 sorted_users = sorted(guild_users.items(), key=lambda x: (-x[1]['level'], -x[1]['experience']))[:show_top] content = "" for idx, (user_id, user_data) in enumerate(sorted_users): content += f"{idx+1}. <@{user_id}> | 等级:{user_data['level']} | 经验:{user_data['experience']}\n" embed = discord.Embed(title=f"{ctx.guild.name} 等级排行榜", description=content, color=discord.Color.gold()) await ctx.send(embed=embed)
额外优化建议
- 你现在的
on_message事件每次触发都要读写一次json文件,高并发场景下很容易出现数据损坏,可以考虑加个定时批量落盘的逻辑,或者用sqlite代替json存储数据 - 可以给排行榜加用户不存在的容错逻辑,避免用户退服后@失效的显示问题
内容的提问来源于stack exchange,提问作者2vw
相关产品推荐
相关产品推荐

