Discord.py如何实现支持异步操作的自定义权限校验装饰器
问题解决方法
你原有代码的核心问题如下:
- 你之前误以为外层装饰器需要异步才能支持异步发送消息,实际上只需要内部的校验函数(predicate)为异步即可,discord.py的
commands.check原生支持异步predicate,完全可以正常执行异步逻辑发送Embed,外层仅作为接收权限参数的工厂函数,不需要定义为异步 - 你错误地直接执行了
predicate(ctx, permission)并把返回值传给commands.check,实际上应该直接把predicate函数本身传给commands.check,由discord.py在命令触发时自动传入ctx参数执行 - predicate不需要额外接收permission参数,直接通过闭包捕获外层传入的permission值即可
- 大量重复的Embed生成逻辑可以抽离复用,减少冗余代码
- 原有代码中部分权限属性名写错,discord.py原生踢出成员权限为
kick_members、封禁成员权限为ban_members,直接写kick、ban会取不到正确权限值
修改后完整代码
def custom_permission(permission): async def predicate(ctx): # 所有者直接放行 if ctx.author.id in config.owners: return True # 权限校验 has_perm = False if permission == "administrator": has_perm = ctx.author.guild_permissions.administrator elif permission == "manage_messages": has_perm = ctx.author.guild_permissions.manage_messages elif permission == "kick": has_perm = ctx.author.guild_permissions.kick_members elif permission == "ban": has_perm = ctx.author.guild_permissions.ban_members elif permission == "manage_guild": has_perm = ctx.author.guild_permissions.manage_guild if has_perm: return True # 权限不足发送提示Embed embed = discord.Embed( timestamp=ctx.message.created_at, description=f"You do not meet the required guild permissions the command \"`{ctx.command.name}`\" requires to be executed.\n\nYou need `{permission.upper()}` Permission in this Guild to be able to execute/run/use this command.", color=242424 ) embed.set_author(name="Insufficient Permissions", icon_url=config.forbidden_img) embed.set_footer(text="Numix", icon_url=config.logo) await ctx.send(embed=embed) return False # 直接将predicate函数传给commands.check,不要提前执行 return commands.check(predicate)
使用方式
和你原有写法完全一致,不需要调整命令上的装饰器代码:
@commands.command() @custom_permission("administrator") async def example(self, ctx, args): ...
内容的提问来源于stack exchange,提问作者BenitzCoding
相关产品推荐
相关产品推荐

