python - 单击命令中的可选参数

标签 python python-click

我正在尝试用 Click 完成一些对于 CLI 解析来说不是很标准的东西,它只能部分工作:

  • 主 CLI 有多个子命令(在下面的示例中为“显示”和“检查”)
  • 这两个命令都可能有可选参数,但参数在它们之前而不是在它们之后
  • 我决定在它“上方”的组中处理该参数,并在上下文中传递值

示例:

import click

@click.group()
@click.argument('hostname', required=False)
@click.pass_context
def cli(ctx, hostname=None):
    """"""
    ctx.obj = hostname
    click.echo("cli: hostname={}".format(hostname))

@cli.command()
@click.pass_obj
def check(hostname):
    click.echo("check: hostname={}".format(hostname))

@cli.command()
@click.pass_obj
def show(hostname):
    click.echo("check: hostname={}".format(hostname))

if __name__ == '__main__':
    cli()

带有主机名的部分有效:

> pipenv run python cli.py  localhost check
cli: hostname=localhost
check: hostname=localhost
> pipenv run python cli.py  localhost show
cli: hostname=localhost
check: hostname=localhost

但是没有主机名的部分不会:

> pipenv run python cli.py show
Usage: cli.py [OPTIONS] [HOSTNAME] COMMAND [ARGS]...

Error: Missing command.

有人知道我应该开始研究的方向吗?

最佳答案

这可以通过覆盖 click.Group 参数解析器来完成,例如:

自定义类:

class MyGroup(click.Group):
    def parse_args(self, ctx, args):
        if args[0] in self.commands:
            if len(args) == 1 or args[1] not in self.commands:
                args.insert(0, '')
        super(MyGroup, self).parse_args(ctx, args)

使用自定义类:

然后要使用自定义组,将其作为 cls 参数传递给 group 装饰器,例如:

@click.group(cls=MyGroup)
@click.argument('hostname', required=False)
@click.pass_context
def cli(ctx, hostname=None):
    ....

怎么做?

之所以可行,是因为 click 是一个设计良好的 OO 框架。 @click.group() 装饰器通常实例化一个 click.Group 对象,但允许使用 cls 参数覆盖此行为。因此,在我们自己的类中继承 click.Group 并覆盖所需的方法是一件相对容易的事情。

在这种情况下,我们覆盖了 click.Group.parse_args(),如果第一个参数与命令匹配而第二个参数不匹配,那么我们将插入一个空字符串作为第一个参数。这会将所有内容放回解析器期望的位置。

关于python - 单击命令中的可选参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44056153/

相关文章:

python - 单击时包含子模块

python - 如何在Python click模块生成的使用消息末尾添加多个空行?

python - 仅删除在 3D numpy 数组的该行中包含重复项的行

python - 如何转义Python相关库中的星号?

python - 如何在 python 中抓取 instagram 帐户信息

python - 如何检查python是否作为click cli命令而不是flask服务器运行?

python click子命令统一错误处理

python - 测试点击 python 应用程序

python - 全局语句的范围

Python:如何从视频中获取显示纵横比?