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)
在这个例子中,有没有办法获得task或task_id在组方法?
这可以通过以下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)