将params发送到click.group()的子命令

Wes*_*man 5 python python-click

如果我click.group()有多个子命令,有没有办法可以将命令行参数传递给组内的子命令?

我知道你可以从组中向下通过context,我知道我可以使用callback在命令之前执行的函数,但我不知道是否有更好的方法来执行此操作而不是使用callback.

一个例子:

@click.group()
def cli():
    pass

@cli.command()
@click.argument('task')
@click.argument('task_id')
def sync(task, task_id):
    click.echo('Synching: {}'.format(task))
Run Code Online (Sandbox Code Playgroud)

在这个例子中,有没有办法获得tasktask_id在组方法?

Ste*_*uch 5

这可以通过以下click.Group.invoke()方法来完成:

自定义类:

class MyGroup(click.Group):
    def invoke(self, ctx):
        ctx.obj = tuple(ctx.args)
        super(MyGroup, self).invoke(ctx)
Run Code Online (Sandbox Code Playgroud)

使用自定义类:

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

@click.group(cls=MyGroup)
@click.pass_context
def cli(ctx):
    args = ctx.obj
    ....
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?

这是有效的,因为它click是一个设计良好的OO框架.该@click.group()装饰通常实例化一个click.Group对象,但允许这种行为是对超缠身cls参数.因此,从click.Group我们自己的班级继承并过度使用所需的方法是相对容易的事情.

在这种情况下,我们过度骑行click.Group.invoke()并抓住参数并将它们放入ctx.obj现场.然后可以在cli()函数中访问它们.

测试代码:

import click

class MyGroup(click.Group):
    def invoke(self, ctx):
        ctx.obj = tuple(ctx.args)
        super(MyGroup, self).invoke(ctx)

@click.group(cls=MyGroup)
@click.pass_context
def cli(ctx):
    args = ctx.obj
    click.echo('cli: {} {}'.format(ctx.invoked_subcommand, ' '.join(args)))

@cli.command()
@click.argument('task')
@click.argument('task_id')
def sync(task, task_id):
    click.echo('Synching: {}'.format(task))

cli('sync task taskid'.split())
Run Code Online (Sandbox Code Playgroud)

结果:

cli: sync task taskid
Synching: task
Run Code Online (Sandbox Code Playgroud)