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

如何基于Discord.py实现服务器专属等级Top10排行榜?

解决Discord机器人服务器专属排行榜的TypeError问题

错误原因

你在top10命令中尝试直接对整个JSON文件里的服务器字典排序,sorted(data.items(), key=lambda item: item[1])中的item[1]是每个服务器对应的用户数据字典,Python不支持直接比较两个字典的大小,因此抛出TypeError: '<' not supported between instances of 'dict' and 'dict'。

修正后的top10命令代码

我们需要先提取当前服务器的用户数据,再按等级+经验值的优先级排序,同时处理用户已离开服务器的情况:

@bot.command()
async def top10(ctx):
    embed = discord.Embed(title="服务器Top10排行榜", color=discord.Colour.gold())
    guild_id = str(ctx.guild.id)
    
    with open('level.json', 'r', encoding='utf-8') as file:
        data = json.load(file)
    
    # 检查当前服务器是否有等级数据
    if guild_id not in data or not data[guild_id]:
        await ctx.send("当前服务器暂无等级数据!")
        return
    
    # 按等级降序、经验值降序排序当前服务器的用户
    sorted_users = sorted(
        data[guild_id].items(),
        key=lambda x: (x[1]['level'], x[1]['experience']),
        reverse=True
    )
    
    # 遍历生成前10条排行数据
    for pos, (user_id, stats) in enumerate(sorted_users[:10], start=1):
        member = ctx.guild.get_member(int(user_id))
        # 兼容用户已离开服务器的情况
        username = member.display_name if member else f"用户({user_id})"
        embed.add_field(
            name=f"{pos}. {username}",
            value=f"等级:{stats['level']} | 经验值:{stats['experience']} XP",
            inline=False
        )
    
    await ctx.send(embed=embed)

关键修正点说明

  1. 锁定当前服务器:通过guild_id = str(ctx.guild.id)精准获取当前服务器的用户数据,实现真正的服务器专属排行榜。
  2. 正确排序逻辑:用key=lambda x: (x[1]['level'], x[1]['experience'])设置排序优先级——先比等级,等级相同再比经验值,符合等级系统的排行规则。
  3. 异常兼容:增加服务器无数据的判断,以及用户离开服务器时的显示处理,避免命令报错。
  4. 编码统一:打开JSON文件时添加encoding='utf-8',和你其他命令保持一致,防止乱码问题。

额外优化建议

  • 可以把JSON文件的读写操作封装成独立函数,减少重复代码。
  • 高频使用的排行榜可以加入缓存机制,避免每次调用都读取文件,提升响应速度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:17:25