Table of Contents generated with DocToc
$ pip3 install click
# clicker.py
import click
@click.command()
@click.argument('name', default='ecmadao')
def arg_with_default(name):
click.echo(name)
名为name的参数会传递给arg_with_default函数,而当我们不添加参数调用的时候则会使用默认值。
$ python3 clicker.py
# ecmadao
$ python3 clicker.py test
# test
需要传递多个参数时,可以设定nargs
。nargs
为-1时代表可以接受多个参数,为1则只能接受一个参数。可以接受多个参数时,多参数以tuple的形式赋值
@click.command()
@click.argument('says', nargs=-1)
@click.argument('name', nargs=1)
def hello_multiply_arg(says, name):
print('{} says:'.format(name))
for said in says:
click.echo(said)
第一个参数nargs=-1
,第二个nargs=-1
,因此在调用时,整体从后往前匹配,最后一个参数赋值给name,其他的作为元组赋值给says
$ python3 clicker.py 1 2 ecmadao
# ecmadao says:
# 1
# 2
$ python3 clicker.py ecmadao
# ecmadao says:
传递一个文件路径作为参数,并设置type=click.File(操作文件的形式)
,则在调用参数的函数内转化为文件对象。
@click.command()
@click.argument('input', type=click.File('rb'))
@click.argument('output', type=click.File('wb'))
def inout(input, output):
while True:
chunk = input.read(1024)
if not chunk:
break
output.write(chunk)
对于文件参数而言,可以使用一个默认的参数-
,来作为特殊的文件输入/输出流
$ python3 clicker.py - hello.txt
# hello
$ python3 clicker.py hello.txt -
option
有三种写法: 完整写法--option
,缩写-op
,不带-
的写法
@click.option('--save', '-s') # 在函数中作为参数名称为save
@click.option('-s') # 参数名称为s
@click.option('--save-local') # 参数名称为save_local
@click.option('--save', '-s', 'saved') # 参数名称为saved
@click.command()
@click.option('--options', '-op', default=2)
def default_option(options):
for option in range(options):
click.echo(option)
$ python3 clicker.py
# 0
# 1
$ python3 clicker.py -op=3
# 0
# 1
# 2
每一个option只支持接收固定长度的参数(argument接收参数个数可以无限制)。多个参数作为元组赋值给option
多次重复调用option则可以不断传入参数(见下文多次传入option)
@click.command()
@click.option('--op', nargs=2)
def multi_options(op):
for option in op:
click.echo(option)
如果传入的参数不是2个则无法正常运行
$ python3 clicker.py --op=0
# Error: --op option requires 2 arguments
$ python3 clicker.py --op=0 1
# 0
# 1
这种方法传入option,不仅仅限制了option的数目,也同时限制了其type
实际作用等同于上面多参数的option,但限制了传递的类型
@click.command()
@click.option('--item', type=(int, str, int))
def tuple_option(item):
for i in item:
click.echo(i)
$ python3 clicker.py --item=s 0 0
# Error: Invalid value for "--item": s is not a valid integer
$ python3 clicker.py --item=0 s 0
# 0
# s
# 0
通过multiple=True
可以在一次调用中无限次数的调用option,并最终将全部的值作为一个tuple代入函数
@click.command()
@click.option('--message', '-m', multiple=True)
def commit(message):
click.echo(' '.join(message))
$ python3 clicker.py -m foo -m bar
# foo bar
option可以有True或False的判断,并且能够在不传入option使用默认值
@click.command()
@click.option('--happy/--no-happy', default=True)
def boolean_option(happy):
if happy:
click.echo('happy')
else:
click.echo('sad')
$ python3 clicker.py --happy
# happy
$ python3 clicker.py --no-happy
# happy
$ python3 clicker.py
# happy
如果不想使用这种True/False的两个参数的判断,则可以使用is_flag=True
@click.command()
@click.option('--happy', is_flag=True)
def boolean_option(happy):
if happy:
click.echo('happy')
else:
click.echo('sad')
若传入option则为True,否则是False
$ python3 clicker.py --happy
# happy
$ python3 clicker.py
# sad
通过type=click.Choice(['a', 'b', 'c'])
,使得只有在Choice内定义的值才能够被接受
@click.command()
@click.option('--arg-type', type=click.Choice(['a', 'b', 'c']))
def choice_option(arg_type):
print(arg_type)
$ python3 clicker.py --arg-type=1
#Error: Invalid value for "--arg-type": invalid choice: 1. (choose from a, b, c)
$ python3 clicker.py --arg-type=a
# a
通过设置prompt
可以使没有option输入时交互式的提醒输入:
prompt=True
,提醒信息为option名称,开头大写prompt='Input your name please'
,提醒信息则为自定义内容
@click.command()
@click.option('--name', prompt=True)
def prompt_option(name):
click.echo('I am {}'.format(name))
# python3 clicker.py
# name: ecmadao
# I am ecmadao
# python3 clicker.py --name=ecmadao
# I am ecmadao
@click.command()
@click.option('--name', prompt='Your name')
def prompt_option(name):
click.echo('I am {}'.format(name))
# python3 clicker.py
# Your name: ecmadao
# I am ecmadao
同时设置prompt
和default
即可达到这个效果
@click.command()
@click.option('--name', '-n', prompt=True, default='ecmadao')
@click.option('--age', '-a', prompt=True, default=24)
def prompt_option_with_default(name, age):
click.echo('I am {}'.format(name))
click.echo('and {} years old'.format(age))
$ python3 clicker.py
# Name [ecmadao]:
# Age [24]:
# I am ecmadao
# and 24 years old
密码输入提示和一般输入提示不同的是,密码输入不会将密码显式的展现出来
hide_input=True
可是隐藏用户的输入;
confirmation_prompt=True
则让用户重复输入以避免输入错误。
@click.command()
@click.option('--password', prompt=True, hide_input=True,
confirmation_prompt=True)
def password_option(password):
click.echo('your password is {password}'.format(password=password))
$ python3 clicker.py
# Password: 123
# Repeat for confirmation: 123
# your password is 123
$ python3 clicker.py
# Password: 123
# Repeat for confirmation: 321
# Error: the two entered values do not match
# Password:
通过设置callback=fun
,可以在命令行调用的时候,触发调用设置好的回调函数。
def print_version(ctx, param, value):
if not value or ctx.resilient_parsing:
return
click.echo('Version 1.0')
ctx.exit()
@click.command()
@click.option('--version', is_flag=True, callback=print_version,
expose_value=False, is_eager=True)
def hello():
click.echo('Hello World!')
在上面这个例子中,使用了配置is_flag=True
,因此,传入--version
时为True,否则为False,而这个True/False则会作为callback中的value参数传入
expose_value=False
,代表了不需要在下面的hello函数中显式的将version参数传入
ctx
代表click.core.Context object
param
代表click.core.Option object
$ python3 clicker.py
# Hello World
$ python3 clicker.py --version
# Version 1.0
def confirm_if_false(ctx, param, value):
if not value:
ctx.abort()
@click.command()
@click.option('--yes', is_flag=True, callback=confirm_if_false,
expose_value=False,
prompt='Are you sure?')
def delete_all_info():
click.echo('Delete all info!')
上面例子中,ctx.abort()
代表输入操作被打断,会退出当前进程,并在command line中console Aborted!
代表被打断
$ python3 clicker.py
# Are you sure? [y/N]: n
# Aborted!
$ python3 clicker.py --yes
# Delete all info!
默认值可以使用函数
@click.command()
@click.option('--username', prompt=True,
default=lambda: os.environ.get('USER', ''))
def hello(username):
print("Hello,", username)
$ python3 clicker.py
# Username [ecmadao1]:
# Hello, ecmadao1
click的echo
是为了兼容Python2和Python3而存在的,其底层实现其实就是print
click会自动帮你生成help
文档,可以通过--help
查看
例如一个这样的文件:
# clicker_help.py
import click
@click.command()
@click.option('--username', prompt=True,
default=lambda: os.environ.get('USER', ''))
def get_user_env(username):
print("Hello,", username)
if __name__ == '__main__':
get_user_env()
$ python3 clicker_help.py --help
Usage: clicker_help.py [OPTIONS]
Options:
--username TEXT
--help Show this message and exit.