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

如何在discord.py中通过自定义装饰器向命令注入参数?

解决discord.py自定义装饰器传递game对象并避免参数缺失错误

问题出在自定义装饰器没有正确保留原命令函数的签名,discord.py需要通过函数签名识别必填参数(比如ctx),仅设置__name__不足以让框架正确解析参数。另外,装饰器的wrapper需要兼容命令可能带的额外参数,保证逻辑复用性。

正确的装饰器实现

首先导入functools来保留函数签名:

import functools
from discord.ext import commands
from your_module import GameState  # 替换为你的GameState实际导入路径

def is_game_running(func):
    @functools.wraps(func)
    async def wrapper(self, ctx, *args, **kwargs):
        # 获取并检查当前频道的游戏状态
        game = self.game_manager.get_game(ctx.channel.id)
        if not game or game.state == GameState.FINISHED:
            return
        # 将验证通过的game对象传递给原命令函数
        return await func(self, ctx, game, *args, **kwargs)
    
    return wrapper

命令函数的使用方式

在类中的命令上应用装饰器,直接接收传递过来的game对象:

class GameCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.game_manager = ...  # 初始化你的游戏管理器实例

    @commands.command()
    @is_game_running
    async def example_command(self, ctx, game):
        # 直接使用game对象编写业务逻辑
        await ctx.send(f"当前游戏状态:{game.state}")

原理说明

  • @functools.wraps(func)会把原函数的元数据(参数签名、文档字符串等)复制到wrapper函数中,让discord.py能正确识别ctx这类必填参数,彻底解决MissingRequiredArgument错误。
  • *args和**kwargs用于兼容带额外用户输入参数的命令,确保装饰器能复用在不同参数结构的命令上。
  • 装饰器完成游戏状态检查后,自动将game对象传递给原命令函数,完全消除了重复的检查代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 09:45:30