如何使用Discord.py实现JSON胜场降序排序的Top10排行榜Embed发送功能
问题修复方案
核心错误说明
- 权限校验逻辑错误:
"Draft manager" or "Draft Manager"只会返回第一个字符串,无法同时匹配两种大小写的角色 - 数据读取逻辑错误:JSON 顶级键是用户 ID,
winss["Wins"]会直接报错,因为不存在这个顶级键 - 缺少排序、取前10、消息发送的完整逻辑
正确代码实现
@client.command() @commands.has_any_role("Draft manager", "Draft Manager") # 修正权限校验,同时匹配两种大小写角色 async def leaderboard(ctx): win_data = await get_win_data() # 可选:过滤掉胜场为0的用户,避免排行榜出现大量无效数据 win_data = {k:v for k,v in win_data.items() if v["Wins"] > 0} # 转换为(用户ID, 胜场数据)元组列表并按胜场降序排序 sorted_users = sorted(win_data.items(), key=lambda x: x[1]["Wins"], reverse=True) # 取前10名 top_10 = sorted_users[:10] # 构造排行榜展示内容 board_content = [] for index, (user_id, data) in enumerate(top_10, start=1): try: # 尝试获取服务器内用户昵称,用户退服则显示ID user = await ctx.guild.fetch_member(int(user_id)) username = user.display_name except: username = f"用户ID:{user_id}" # 可选:前三名增加特殊标识 rank_icon = "" if index == 1: rank_icon = "🥇 " elif index == 2: rank_icon = "🥈 " elif index == 3: rank_icon = "🥉 " board_content.append(f"{rank_icon}{index}. {username} - {data['Wins']} 胜") # 无数据兜底处理 if not board_content: board_content = ["暂无有效胜场数据"] # 构造Embed并发送 balemb = discord.Embed(title="Draft 排行榜", colour=discord.Colour.blue()) balemb.add_field(name="胜场榜", value="\n".join(board_content), inline=False) await ctx.send(embed=balemb)
其他优化建议
- 工具函数内的文件操作建议增加异常捕获,避免JSON文件损坏、权限不足等问题导致程序崩溃
- 如果用户量超过100,建议把数据存储替换为SQLite等轻量数据库,比JSON读写效率更高、数据一致性更好
- 可以增加调用者排名展示,比如Embed底部加一行小字显示当前用户的排名和胜场
内容的提问来源于stack exchange,提问作者Alex is funny
相关产品推荐
相关产品推荐

