最近看的一个开源项目用到了Click包来代替argparse实现命令行传参,简单学习一下Click。Click是一个用于快速创建命令行界面的python包,使用装饰器来把函数方法装饰为命令行接口。

基本用法

官方给的hello.py例子。

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()

可以看到click使用@click.command()把hello变成命令行接口,添加了两个count和name两个选项(可以指定默认值、也可以执行时输入),输出使用click.echo。执行的话可以直接python hello.py --count=3,同时click会自动使用指定的help参数和函数字符串生成帮助文档。
生成的帮助文档:

$ python hello --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.

常用功能

click.option

option从命令行读取参数值然后传递给函数,常用的设置参数有:

  • default
  • help
  • type:支持click.Path()、click.Choice(choices)等高级类型;支持tuple指定多个参数的不同类型
  • nargs:支持多个参数,转为tuple传给函数
  • prompt
  • required
  • multiple:可以实现git commit -m foo -m bar的效果

option还支持很多其他的功能,比如密码输入、确认提示、从环境或文件中取得参数值、对某些参数执行回调函数等,其他参数可以参考官方的options文档,例子和文档都很完善,就不搬运了。
命令行传递参数还可以使用**@click.argument()来实现,和option的用法大致相同,可以接受任意**数量的参数,下面是和option的一些不同:

  • 不支持自动提示缺少的输入(prompt)
  • 不支持作为标志
  • option的值可以从环境变量中提取
  • option在帮助页面中完整记录

click.group

装饰器command可以把函数变为命令行接口,而group装饰器可以用来连接不用的命令,下面是一个使用了两种方式将命令行添加到命令组中的例子。

$group.py
@click.group()
def cli():
    pass

@cli.command()
def initdb():
    click.echo('Initialized the database')

@click.command()
def dropdb():
    click.echo('Dropped the database')

cli.add_command(dropdb)
    
if __name__ =='__main__':
    cli()

然后就可以使用python group.py initdb/dropdb来分别调用不同的函数。同样的,click也会分别对组中不同的命令生成帮助文档。


参考:
http://funhacks.net/2016/12/20/click/
https://isudox.com/2016/09/03/learning-python-package-click/