8

如果我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))

在这个例子中,有没有什么方法可以获取tasktask_id在 group 方法中?

4

1 回答 1

8

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

自定义类:

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

使用自定义类:

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

@click.group(cls=MyGroup)
@click.pass_context
def cli(ctx):
    args = ctx.obj
    ....

这是如何运作的?

这是有效的,因为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())

结果:

cli: sync task taskid
Synching: task
于 2017-05-19T21:28:36.497 回答