Discord.py机器人leaderboard排行榜命令无报错不生效求助
问题根因
- 命令参数
x默认值为0,如果你触发命令时没有传入参数(例如仅发送!lb),会直接导致第一个Embed标题显示Top 0 Richest People,同时循环中的终止条件if index == x: break永远无法触发,index会从1开始持续递增直到遍历完所有用户 - 你使用总金额作为
leader_board字典的key,相同金额的用户会被后续遍历到的同金额用户覆盖,导致排行榜丢失大量用户数据 client.get_user()仅能从本地缓存中查询用户,如果用户不在缓存中会返回None,直接访问member.name会抛出AttributeError,而Discord.py默认会吞掉命令执行过程中的异常,所以你看不到报错,只会表现为后续的发送代码无响应get_bank_data声明为async函数但内部全是同步IO操作,虽然不直接导致错误,但存在性能隐患
修复方案
- 将参数
x的默认值改为合理值,例如10,同时增加参数合法性校验,限制最大显示数量避免Embed超出Discord长度限制 - 调整排行榜数据存储结构,避免同金额用户覆盖的问题
- 把
client.get_user()替换为await client.fetch_user()主动拉取用户数据,同时增加异常判断避免拉取失败报错 - 可按需增加命令全局异常捕获逻辑方便后续排查问题
修复后代码
@client.command(aliases = ['lb']) async def leaderboard(ctx, x = 10): # 限制最少显示1条,最多显示100条,避免Embed超出Discord官方限制 x = min(max(x, 1), 100) users = await get_bank_data() # 调整存储结构为元组列表,避免同金额用户被覆盖 leader_board = [] for user_id_str in users: user_id = int(user_id_str) total_amount = users[user_id_str]["wallet"] + users[user_id_str]["bank"] leader_board.append((-total_amount, user_id)) # 用负数存储金额,升序排序即可实现金额降序效果 # 完成排序 leader_board.sort() em = discord.Embed( title = f"Top {x} 富豪榜", description = "排名依据为钱包+银行的总资产", color = discord.Color(0xfa43ee) ) index = 1 for minus_amt, user_id in leader_board: total_amt = -minus_amt try: member = await client.fetch_user(user_id) except: # 拉取不到用户时显示默认占位符 name = "未知用户" else: name = member.name em.add_field( name = f"{index}. {name}", value = f"总资产:{total_amt}", inline = False ) if index == x: break index += 1 await ctx.send(embed = em) # 可按需把get_bank_data改为同步函数,减少不必要的async包装 async def get_bank_data(): with open('mainbank.json','r') as f: users = json.load(f) return users
内容的提问来源于stack exchange,提问作者Hiresh Verma
相关产品推荐
相关产品推荐

