首页 > 解决方案 > discord.py - 使用长查询和不带双引号的标志

问题描述

如何在没有双引号的情况下输入较长的文本(例如歌曲)?

我的命令如下所示:

@commands.command(brief="play [track] <options>")
async def play(self, ctx, query: str, *, options: Options) -> None:

我只能这样使用它:播放“Sweet Dreams” --now而不是播放 Sweet Dreams --now


如果我将 * 放在查询前面,如下所示:

@commands.command(brief="play [track] <options>")
async def play(self, ctx, *, query: str, options: Options) -> None:

我收到此错误: Command raised an exception: TypeError: play() missing 1 required keyword-only argument: 'options'


我的标志如下所示:

class Options(commands.FlagConverter, delimiter=" ", prefix="--"):
    next: bool = False
    now: bool = False

标签: pythonpython-3.xdiscorddiscord.py

解决方案


after 参数*收集命令尚未收集的所有内容。您的代码出错了,因为 discord.py 只需要零个或一个仅关键字参数:它将所有内容都放入其中,因此您定义的第二个参数将一无所有。

相反,您可以将整个内容放入一个仅限关键字的参数中,然后从那里手动解析任何选项。

您需要一种方法来区分文本的一部分以及选项的开始位置。假设您希望用户将选项放在他们自己的行上,这样最后一个换行符将标记选项的开始。

@commands.command(brief="play [track] <options>")
async def play(self, ctx, *, content: str) -> None:
    query, _, options = content.rpartition("\n")

    if (options := options.strip()).startswith("--"):
        # There are actually options here
        options = Options.convert(options)
    else:
        # This line is actually the last line of the query and no option was given
        query += f"\n{options}"

    ...

如果您不熟悉(options := options.strip()),那就是海象运算符。它相当于options = options.strip()但节省了一些代码。如果您使用的是 Python <3.8,您可以将后者放在if.


推荐阅读