Python中创建命令行神器——Click

 

click是用 Python 写的一个第三方模块,用于快速创建命令行。我们知道,Python 内置了一个 Argparse 的标准库用于创建命令行,但使用起来有些繁琐,Click 相比于 Argparse,就好比 requests 相比于 urllib。

首先需要安装click模块,用pip安装

快速使用

Click 的使用大致有两个步骤:

  1. 使用 @click.command() 装饰一个函数,使之成为命令行接口;
  2. 使用 @click.option() 等装饰函数,为其添加命令行选项等。

它的一种典型使用形式如下:

import click

 

@click.command()

@click.option('--count', default=1, help='Number of greetings.')

@click.option('--name', prompt='Your name', help='The person to greet.')

def hello(count, name):

    """Simple program that greets NAME for a total of COUNT times."""

    for x in range(count):

        click.echo('Hello %s!' % name)

 

if __name__ == '__main__':

    hello()

 

在上面的例子中,函数 hello 有两个参数:count 和 name,它们的值从命令行中获取。

  • @click.command() 使函数 hello 成为命令行接口;
  • @click.option 的第一个参数指定了命令行选项的名称,可以看到,count 的默认值是 1;
  • 使用 click.echo 进行输出是为了获得更好的兼容性,因为 print 在 Python2 和 Python3 的用法有些差别。

 

看看执行情况:

$ python hello.py
Your name: Ethan           # 这里会显示 'Your name: '(对应代码中的 prompt),接受用户输入
Hello Ethan!
 
$ python hello.py --help   # click 帮我们自动生成了 `--help` 用法
Usage: hello.py [OPTIONS]
 
  Simple program that greets NAME for a total of COUNT times.
 
Options:
  --count INTEGER  Number of greetings.
  --name TEXT      The person to greet.
  --help           Show this message and exit.
 
$ python hello.py --count 3 --name Ethan    # 指定 count 和 name 的值
Hello Ethan!
Hello Ethan!
Hello Ethan!
 
$ python hello.py --count=3 --name=Ethan    # 也可以使用 `=`,和上面等价
Hello Ethan!
Hello Ethan!
Hello Ethan!
 
$ python hello.py --name=Ethan              # 没有指定 count,默认值是 1
Hello Ethan!


 

函数秒变 CLI


import click
@click.command()
def hello():
click.echo('Hello World!')
 
@click.command() 装饰器把 hello() 方法变成了 Command 对象,当它被调用时,就会执行该实例内的行为。而 --help 参数就是 Command 对象内置的参数。
不同的 Command 实例可以关联到 group 中。group 下绑定的命令就成为了它的子命令,参考下面的代码:
@click.group()
def cli():
pass
@click.command()
def initdb():
click.echo('Initialized the database')
@click.command()
def dropdb():
click.echo('Dropped the database')
cli.add_command(initdb)
cli.add_command(dropdb)
 
命令行的参数是不可或缺的,Click 支持对 command 方法添加自定义的参数,由 option() 和 argument() 装饰器实现。
@click.command()
@click.option('--count', default=1, help='number of greetings')
@click.argument('name')
def hello(count, name):
for x in range(count):
click.echo('Hello %s!' % name)

Commands and Groups

Click最重要的特征之一是任意嵌套的命令行,这个特性通过command和group(MultiCommand)实现。

1. 回调

对一个常规的command来说,只要command运行,回调必然执行,除非参数的回调函数打断了它,比如--help

但对于group和多个command来说,情况不同。回调仅在子命令调用时执行。

但对于group和多个command来说,情况不同。回调仅在子命令调用时执行。

@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()
def sync():
click.echo('Synching')
 
 
Here is what this looks like:
 
$ tool.py
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
Synching

针对项目:如果已知函数名,option和cli效果是一样的;但是动态加载和不知道函数名的时候(也是为了接口方便),用cli可以实时根据获得的函数名来执行。