繁体   English   中英

如何将 arguments 从自定义装饰器注入到 discord.py 中的命令?

[英]How to inject arguments from a custom decorator to a command in discord.py?

我正在开发一个机器人,它可以跟踪不同渠道中的各种基于文本的游戏。 在运行相关游戏的通道之外使用的命令当然应该什么也不做,并且它们也不应该在游戏未运行时激活(例如,当新游戏即将开始时)。 因此,几乎我所有的命令都以相同的几行代码开头

@commands.command()
async def example_command(self, ctx):
    game = self.game_manager.get_game(ctx.channel.id)
    if not game or game.state == GameState.FINISHED:
        return

我宁愿只装饰所有这些方法。 Discord.py 方便地提供了一个“检查”装饰器系统来自动执行这些类型的检查,但这不允许我将game object 传递给命令。 由于每个命令都需要对此 object 的引用,无论如何我每次都必须再次检索它,理想情况下我只想将它传递给命令。

我对装饰器的天真尝试如下所示

def is_game_running(func):
    async def wrapper(self, ctx):
        # Retrieve `game` object here and do some checks
        game = ...

        return await func(self, ctx, game)

    wrapper.__name__ = func.__name__

    return wrapper

# Somewhere in the class
@commands.command()
@is_game_running
async def example_command(self, ctx, game):
    pass

但是,这给了我一个非常神秘的错误“discord.ext.commands.errors.MissingRequiredArgument:ctx 是缺少的必需参数。”

我已经尝试了一些变体,使用*args等......但似乎没有任何效果。

discord.py 为上下文 object 提供了一个方便的bot属性,使您可以从上下文中获取 bot 实例。 你可以从那里得到你的游戏。

我将使用 discord.py 的检查系统作为示例。

def is_game_running():
    def predicate(ctx):
        game = ctx.bot.game_manager.get_game(ctx.channel.id)

        ... # do some checks

        return result # result of the check. Must be true or false
    return commands.check(predicate)

@commands.command()
@is_game_running()
async def example_command(self, ctx, game):
    pass

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM