Python 使用Click自定义命令行参数

简介:

官方文档

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

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值