Discord.py Bot调用带*参数的命令函数报TypeError问题求助
Discord.py 跨命令调用带多词接收参数的报错修复
问题根因
被@command.command()装饰的函数会被discord.py包装为Command对象,不再是你定义的原始协程。函数签名里*后的参数是仅限关键字传参,不支持按位置顺序传值,你之前直接按位置顺序传ctx, text的写法不符合参数规则,才会触发参数数量不匹配、缺失必填参数的报错。
如果去掉*,text会变成普通位置参数,虽然内部调用不报错,但用户直接触发命令时只能拿到第一个空格前的内容,无法接收多词长度的文本,不符合功能要求。
修复方案
方案一(工程实践首选):抽离公共逻辑
把两个命令复用的逻辑拆成独立的无装饰器协程,两个命令分别调用这个公共函数即可,从根源上避开命令包装层的参数解析规则,后期维护也更方便。
# 抽离公共逻辑,不添加命令装饰器 async def _output_text(ctx, content): await ctx.send(content) @command.command() async def test1(self, ctx): text = "hi john" await _output_text(ctx, text) @command.command() async def test2(self, ctx, *, text): # 保留*,用户直接调用时可正常接收带空格的长文本 await _output_text(ctx, text)
方案二:用上下文提供的invoke方法调用
discord.py的上下文对象内置了ctx.invoke方法专门处理跨命令调用,注意*后的参数必须以关键字参数形式传入,不能按位置传:
@command.command() async def test1(self, ctx): text = "hi john" # Cog类内可直接传入类方法作为调用目标,keyword-only参数必须指定参数名传值 await ctx.invoke(self.test2, text=text) @command.command() async def test2(self, ctx, *, text): await ctx.send(text)
非Cog结构的代码可以先通过bot实例获取命令对象再调用:
await ctx.invoke(bot.get_command("test2"), text=text)
内容的提问来源于stack exchange,提问作者Huskclaw
相关产品推荐
相关产品推荐

