Discord.py:如何在检查的谓词函数中访问自我?

问题描述 投票:0回答:1

我花了至少一天的时间试图找到问题的答案,包括至少花几个小时与嵌套装饰器混在一起,但我似乎无法弄清楚。

我正在使用 Discord.py,它是

commands.check
“装饰器生成器”,但我认为问题(可能是解决方案)可能并不是真正特定于 Discord.py 的。

问题陈述如下:

我想在

check
上声明一个 Discord.py
Cog
,但需要访问 Cog 的实例来执行一些数据获取以解决检查问题。

现在,Discord.py 声明检查的语法是在给定谓词函数的情况下调用 commands.check 函数,该谓词函数又返回一个可应用于任何 Cog 方法的装饰器,例如

def custom_check():
  async def predicate(ctx):
    # I'll need to do some data fetching here...
    return True
  return commands.check(predicate)

class MyCog(commands.Cog):
  @commands.command()
  @custom_check()
  async func(self, ctx):
    pass

  async def some_data_fetching():
    pass

我一直在想办法解决这个问题,但无法解决这个问题。我一直在探索如何创建一个可以访问 self 的包装闭包,但是

  1. 我无法让它工作('predicate called'从不打印)和
  2. 我仍然无法弄清楚如何将 self 注入
    predicate
    函数——在任何方法被调用并且 self 可用之前,需要先调用
    commands.check
    (并将谓词传递给它)。
def custom_check():
    async def predicate(ctx):
        print('predicate called')
        return False

    check_decorator = commands.check(predicate)

    def custom_decorator(f):
        async def wrapper(self, *args, **kwargs):
            return await f(self, *args, **kwargs)
        return wrapper

    return lambda f: check_decorator(custom_decorator(f))

非常感谢任何帮助或建议。

python discord.py python-decorators
1个回答
0
投票

解决方案:使用

ctx.cog
ctx.args

def custom_check():
  async def predicate(ctx):
    data = await ctx.cog.some_data_fetching()
    return data.checks_out
  return commands.check(predicate)

我决定仔细查看提供的上下文 (

ctx
) 并意识到它同时具有 args 属性(具有传递给命令调用的参数,包括
self
)以及
cog
属性引用调用的命令所在的 cog。他们中的任何一个都可以让我做我需要做的事。

感谢您成为我的听众。

© www.soinside.com 2019 - 2024. All rights reserved.