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

discord.py 如何获取命令所需全部权限 实现类似Dank Memer的帮助命令权限展示

自定义帮助命令提取命令所需权限的正确实现方案

你当前使用的传入假ctx触发检查异常、遍历异常栈读取本地权限变量的方案属于依赖源码细节的黑魔法,存在两个核心缺陷:

  • 强依赖discord.py内置权限检查的内部实现,版本迭代调整源码变量名后会直接失效
  • 完全无法兼容自定义装饰器:自定义检查的判断逻辑没有内置的异常抛出流程,也不存在约定命名的perms本地变量,自然无法通过异常栈解析拿到数据

可靠实现思路

不要靠运行时触发异常解析变量,要利用检查函数的可挂载属性,在定义检查阶段就把需要展示的权限元数据显式存储,运行时直接读取即可。

1. 改造检查的元数据存储逻辑

  • 对discord.py内置的commands.has_permissions系列装饰器:不需要手动传值触发异常,这类装饰器生成的检查函数本身会把权限参数存在闭包的perms变量中,可以直接从闭包读取,无需侵入式触发异常。
  • 对自定义装饰器:编写自定义检查时,直接把需要展示的权限、特殊规则作为属性挂载在检查谓词函数上,从根源解决元数据读取的兼容性问题。示例:
def require_custom_role(role_id: int):
    async def role_checker(ctx):
        # 实际运行时的权限判断逻辑
        return ctx.author.get_role(role_id) is not None
    # 把帮助页需要展示的元信息直接挂在函数上
    role_checker.required_perms = {}
    role_checker.required_display_text = f"需要持有ID为{role_id}的指定角色"
    return commands.check(role_checker)

2. 跨检查统一收集权限的工具函数

遍历命令本身、所属父分组的全部检查,逐一对接内置检查、自定义检查的元数据来源,汇总得到完整的权限要求:

def fetch_command_requirements(command: commands.Command):
    required_perms = set()
    extra_notes = []
    # 合并命令自身、所有上级父分组的检查规则
    all_checks = command.checks.copy()
    parent_group = command.parent
    while parent_group:
        all_checks.extend(parent_group.checks)
        parent_group = parent_group.parent

    for check in all_checks:
        # 读取内置权限检查的闭包变量
        if hasattr(check, "__closure__"):
            for closure_var in check.__closure__:
                if closure_var.name == "perms" and isinstance(closure_var.cell_contents, dict):
                    required_perms.update(closure_var.cell_contents.keys())
        # 读取自定义检查挂载的元数据
        if hasattr(check, "required_perms"):
            required_perms.update(check.required_perms.keys())
        if hasattr(check, "required_display_text"):
            extra_notes.append(check.required_display_text)
    
    return {
        "server_permissions": list(required_perms),
        "custom_requirements": extra_notes
    }

方案优势

  • 全兼容:不管是discord.py内置权限检查,还是自定义装饰器写的校验规则,都能稳定读取到需要展示的权限信息
  • 低侵入:不需要靠触发异常的黑魔法流程,不会因为版本迭代、自定义逻辑不同导致解析失败
  • 易扩展:后续新增任意自定义校验规则时,只需要在检查函数上挂载对应元数据,就能自动被帮助命令读取展示,可实现和Dank Memer一致的命令权限展示效果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 05:27:09