簡體   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