作者:HelloGitHub-Prodesire

 

HelloGitHub 的《讲解开源项目》系列,项目地址:https://github.com/HelloGitHub-Team/Article

一、前言

在上两篇文章中,我们介绍了 click中的”参数“和“选项”,本文将继续深入了解 click,着重讲解它的“命令”和”组“。

本系列文章默认使用 Python 3 作为解释器进行讲解。 若你仍在使用 Python 2,请注意两者之间语法和库的使用差异哦~

二、命令和组

Click 中非常重要的特性就是任意嵌套命令行工具的概念,通过 Command 和 Group (实际上是 MultiCommand)来实现。

所谓命令组就是若干个命令(或叫子命令)的集合,也成为多命令。

2.1 回调调用

对于一个普通的命令来说,回调发生在命令被执行的时候。如果这个程序的实现中只有命令,那么回调总是会被触发,就像我们在上一篇文章中举出的所有示例一样。不过像 --help 这类选项则会阻止进入回调。

对于组和多个子命令来说,情况略有不同。回调通常发生在子命令被执行的时候:

@click.group() @click.option('--debug/--no-debug', default=False) def cli(debug):     click.echo('Debug mode is %s' % ('on' if debug else 'off'))  @cli.command()  # @cli, not @click! def sync():     click.echo('Syncing')

执行效果如下:

Usage: tool.py [OPTIONS] COMMAND [ARGS]...  Options:   --debug / --no-debug   --help                Show this message and exit.  Commands:   sync  $ tool.py --debug sync Debug mode is on Syncing

在上面的示例中,我们将函数 cli 定义为一个组,把函数 sync 定义为这个组内的子命令。当我们调用 tool.py --debug sync 命令时,会依次触发 cli 和 sync 的处理逻辑(也就是命令的回调)。

2.2 嵌套处理和上下文

从上面的例子可以看到,命令组 cli接收的参数和子命令 sync 彼此独立。但是有时我们希望在子命令中能获取到命令组的参数,这就可以用 Context 来实现。

每当命令被调用时,click 会创建新的上下文,并链接到父上下文。通常,我们是看不到上下文信息的。但我们可以通过 pass_context 装饰器来显式让 click 传递上下文,此变量会作为第一个参数进行传递。

@click.group() @click.option('--debug/--no-debug', default=False) @click.pass_context def cli(ctx, debug):     # 确保 ctx.obj 存在并且是个 dict。 (以防 `cli()` 指定 obj 为其他类型     ctx.ensure_object(dict)      ctx.obj['DEBUG'] = debug  @cli.command() @click.pass_context de