简介:
Click 用于以可组合的方式使用尽可能少的代码创建漂亮的命令行界面。
特点:
- 命令的任意嵌套
- 自动帮助页面生成
- 支持在运行时延迟加载子命令
安装:
pip install click
简单使用
import click
@click.command()
def demo():
click.echo("test demo")
if __name__ == "__main__":
demo()
# 命令行输入 Python test.py 就会输出 test demo
# 查看帮助信息 python test.py --help
参数 @click.argument()
import chardet
import click
@click.command()
@click.argument("user")
def get_user(user):
"""
指定一个参数 user 必须输入
:param user:
:return:
"""
click.echo(user)
@click.command()
@click.argument("arg", nargs=2)
# @click.argument("arg", nargs=-1)
def get_more_args(arg):
"""
指定多个可变参数,如果 nargs=-1的话,会返回一个参数元组
:param arg:
:return:
"""
click.echo(arg)
@click.command()
@click.argument("in_file", type=click.File("rb", encoding="utf-8"))
@click.argument("out_file", type=click.File("wb", encoding="utf-8"))
def copy_file(in_file, out_file):
"""
复制文件,type=click.File("r", encoding="utf-8") 指定文件读写模式,编码
:param in_file: 源文件地址
:param out_file: 新文件地址
:return:
"""
while True:
chunk = in_file.read(1024)
if not chunk:
break
out_file.write(chunk)
@click.command()
@click.argument("filename", type=click.Path(exists=True))
def get_file_path(filename):
"""
文件路径参数,type=click.Path(exists=True) 可以检查文件是否存在
:param filename:
:return:
"""
# 清除终端屏幕
click.clear()
# click.echo(click.format_filename(filename))
click.echo(click.style(click.format_filename(filename), bg="blue", fg="red")) # 输出颜色
# secho 整合 echo 和 style
click.secho('Hello World!', fg='green')
click.secho('Some more text', bg='blue', fg='white')
@click.command()
@click.argument("app_or_url_file")
def start_app(app_or_url_file):
"""
打开指定的 URL, app, 文件
:param app_or_url_file: URL / app(必须用双引号) / 文件
:return:
"""
click.launch(app_or_url_file)
if __name__ == "__main__":
# get_user()
# get_more_args()
# copy_file()
# en = get_encoding(r"C:\Users\zhangjinlong\Desktop\面试\面试题.txt")
# print(type(en), en)
get_file_path()
选项 @click.option()
# -*- coding: utf-8 -*-
# @Time: 2021/11/12 13:45
import click
"""
@click.optino("短选项", "长选项", "选项名",, default=默认值, prompt=提示信息, help=帮助信息)
自定义命令行参数,命令行内输入: 命令 + 值
没有指定默认值的话,默认选项值类型为string
# 函数形参传递
@click.option("-n", "--num", "num") # 指定了选项的名称为num,函数形参传递 num
@click.option("-n", "--user-name") # 没有指定选项的名称,函数形参传递第一个长选项的名字,并且自动使用下划线_, user_name
@click.option("-n") # 只有一个长选项,没有指定选项名称,函数形参传递段选项名称 n
@click.option( # 选项
"--age", # 指定参数命令
type=int, # 指定参数类型。当指定nargs为多个参数时,type可以指定每个参数的类型。
例如:type=(str, int) 第一个参数必须是str,第二个参数必须是int
# type=click.Choice(["MD5", "SHA1"], case_sensitive=False) 可选枚举值参数,case_sensitive忽略大小写
default=0, # 默认值
envvar="USERNAME", # 指定环境变量的值
show_default=True, # 帮助信息内是否展示默认值.
如果设置为True, 帮助信息则会显示 default指定的值;
如果设置指定的值,帮助信息显示指定的值:show_default="os.environ.get('USERNAME')"
required=True, # 是否必填
nargs=2, # 指定传入多参数 当参数为多个时,可以(非必须)指定每个参数的类型type=(str, int),存储为一个元组
prompt="输入年龄:", # 如果没有输入此选项,则显示提示信息来提示用户输入. 如果设置为True,则提示信息为对应的选项名称;如果设置为自定义str类型的提示信息,则直接展示。
multiple=True, # 同一个选项可以使用多次。传递此参数时,default参数必须是lsit or tuple,否则将被解析为单个字符的列表
count=True, # 用于统计输入的选项次数,返回的是次数,int类型。例如 输入 -vvv, 则返回 3 。注意:开启后,使用此选项时不能带参数
hide_input=True, 隐藏输入信息 ,一般用于密码输入
confirmation_prompt=True, 二次输入确认
type=click.IntRange(0, 10, clamp=True) # 限制取值范围,clamp=True 表示超过边界值后,取边界值
)
参数和选项的差异:
1、选项值可以从环境变量中获取
2、选项在帮助页面有完整的记录
参数的类型:
str/ click.STRING: 表示 unicode 字符串的默认参数类型。
int/ click.INT: 只接受整数的参数。
float/ click.FLOAT: 只接受浮点值的参数。
bool/ click.BOOL:
click.UUID: 接受 UUID 值的参数。这不是自动猜测的,而是表示为uuid.UUID。
"""
@click.command()
@click.argument("name")
@click.option("--age", default=0, prompt="输入年龄:", required=True, type=int, show_default=True, help="帮助信息:int类型 必填 年龄")
def demo(name, age):
click.echo(f"{name}, {age}")
@click.command()
@click.option("--score", nargs=2, type=(str, int), prompt="属性分数:", default=0, help="int类型,非必填,分数")
def score(score):
"""
运行:python .\demo_click_argument_option.py --score 100 200 输出: ('100', 200)
:param score:
:return:
"""
click.echo(score)
# click.echo(os.environ.keys())
@click.command()
@click.option("--path", envvar="PATHS", multiple=True, type=click.Path())
def perform(path):
click.echo(path) # ('.\\demo_click_argument_option.py',)
@click.command()
@click.option("-n", "--num", "num", default=1, prompt=True, help="print times")
# @click.option("-u", "--user-name", "user_name", default="None", prompt="input your name:", help="name")
@click.option("-u", "--user-name", "user_name", default="None", prompt=True, help="name")
def demos(num, user_name):
for i in range(num):
click.echo(f"hello, {user_name}")
@click.command()
@click.option("-v", count=True)
def count(v):
"""
count=True 用于统计输入的 -v次数返回的是次数。例如 输入 -vvv, 则返回 3 。注意:开启后,此选项不能带参数
:param v:
:return:
"""
click.echo(v)
@click.command()
@click.option("-ht", "--hash-type", type=click.Choice(["MD5", "SHA1"], case_sensitive=False))
def choice_enum_args(hash_type):
"""
可选枚举值参数
:param hash_type:
:return:
"""
click.echo(hash_type)
@click.command()
@click.option("-p", "--password", prompt=True, hide_input=True, confirmation_prompt=True)
def encode(password):
"""
hide_input=True 隐藏输入信息 ,一般用于密码输入,confirmation_prompt=True 二次输入确认
:param password:
:return:
"""
click.echo(password)
@click.command()
@click.option("-u", "--user", prompt=True, default=os.environ.get("USERNAME"), show_default=True)
def get_defualt(user):
click.echo(user)
@click.command()
@click.option("-v", "--version", is_flag=True, expose_value=False, is_eager=True)
def is_flag_use(version):
"""
设置 is_flag=True 后,使用时可以传选项,也可以不传选项. expose_value 可防止将毫无意义的参数传递给回调方法
:param version:
:return:
"""
click.echo("is_flag_use .")
def callback_test(context, param, value):
"""
退出
:param context:
:param param:
:param value:
:return:
"""
print(context)
print(param)
print(value)
if not value or context.resilient_parsing:
return
click.echo("version 1.0")
context.exit()
@click.command()
@click.option("-v", "--version", is_flag=True, callback=callback_test, expose_value=False)
def callback_use(version):
click.echo("result end - this will not run.")
def delete_test(context, param, value):
"""
拒绝,终止程序
:param context:
:param param:
:param value:
:return:
"""
if not value:
context.abort()
@click.command()
# @click.option("--yes", "-y", is_flag=True, callback=delete_test, expose_value=False, prompt="are you sure delete ?")
@click.confirmation_option("-y", prompt="are you sure delete?")
def delete_use():
click.echo("delete_use.")
@click.command()
@click.option("--username", "-u", envvar="USERNAME", help="SYS USERNAEM")
def get_env_var(username):
"""
从环境变量中取值,envvar 指定环境变量的key
:param username:
:return:
"""
click.echo(username)
@click.command()
@click.option("-c", type=click.IntRange(0, 10, clamp=True))
# @click.option("-c", type=click.IntRange(0, 10, clamp=False))
def intrange(c):
"""
限制取值范围 type=click.IntRange(0, 10, clamp=True)
clamp=True 表示超过边界值后,取边界值
:param c:
:return:
"""
click.echo(c)
if __name__ == '__main__':
# demo()
# score()
perform()
分组 @click.group()
# -*- coding: utf-8 -*-
# @Time: 2021/11/12 13:31
"""
将命令分组,直接使用 @组函数名.command() 代替@click.command()
"""
import click
@click.group()
def cli():
pass
@cli.command()
def init_db():
click.echo("database init success")
@cli.command()
def del_db():
click.echo("truncat database all tables succcess")
if __name__ == '__main__':
cli()
# 命令行输入
# python .\demo_click_group.py init-db
# python .\demo_click_group.py del-db
# -*- coding: utf-8 -*-
# @Time: 2021/11/12 13:39
"""
推荐
将命令分组,都是用@click.command() 最后用 [组名].add_command([命令函数名]) 来逐个添加要使用的命令
好处是可以决定是否启用某个命令
"""
import click
@click.group()
def cli():
pass
@click.command()
def init_db():
click.echo("database init success")
@click.command()
def del_db():
click.echo("truncat database all tables succcess")
@click.command()
@click.option("--username", "-u", envvar="USERNAME", help="SYS USERNAEM")
def get_env_var(username):
"""
从环境变量中取值,envvar 指定环境变量的key
:param username:
:return:
"""
click.echo(username)
if __name__ == '__main__':
# 添加/注册命令
cli.add_command(init_db)
cli.add_command(del_db)
cli.add_command(get_env_var)
# 调用
cli()
# python .\demo_click_group_add.py init-db
# python .\demo_click_group_add.py del-db
# python .\demo_click_group_add.py get-env-var -u yourusername