Python 命令行之旅:深入 click 之子命令篇
作者: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