首页Python【Python计算生态】c...

【Python计算生态】click——创建命令行接口(CLI)

Python受欢迎的原因之一就是其计算生态丰富,据不完全统计,Python 目前为止有约13万+的第三方库。

本系列将会陆续整理分享一些有趣、有用的第三方库。

文章配套代码获取有以下两种途径:
  • 通过百度网盘获取:
链接:https://pan.baidu.com/s/1FSGLd7aI_UQlCQuovVHc_Q?pwd=mnsj 提取码:mnsj
  • 前往GitHub获取
https://github.com/returu/Python_Ecosystem





01
简介

Click是一个用于创建命令行界面(CLI)的Python第三方库,由Flask的作者Armin Ronacher开发。它通过装饰器和简洁的API设计,使得编写命令行工具更加直观和高效,让开发者可以轻松地将Python函数转换为命令行工具。Click具有以下三大特点:
  • 简洁的装饰器语法:通过装饰器定义命令和参数,代码简洁且易读;
  • 多命令支持:提供了分组命令功能,支持多层级命令结构,适用于大型 CLI 项目;
  • 自动生成帮助文档:自动生成 –help 信息,无需手动编写;
  • 类型转换:支持多种数据类型(如整数、文件路径、日期等)的自动校验和转换。
直接使用pip
pip install click
GitHub页面:
https://github.com/pallets/click

02
使用

  • 1、简单命令:

Click通过 click.command() 装饰器将函数转换为 Click 命令行工具。最简单的情况下,只需用这个装饰器装饰函数,即可将其变为可调用的脚本:

### 文件名:ex_1.py ###

import click

@click.command()
def hello():
    click.echo("Hello World!")
    
if __name__ == '__main__':
    hello()
在上述代码中:
  • @click.command():是一个装饰器,它将hello函数转换为一个命令行命令。
  • click.echo():用于在命令行输出文本,它比Python内置的print()函数更适合在命令行环境中使用,因为它能更好地处理Unicode字符和不同操作系统的换行符。

将上述代码保存为 ex_1.py,然后在命令行中运行,后输出结果为:

>>> python ex_1.py
# 输出:Hello World!


  • 2、添加参数:
click库中,option()argument()是两个非常重要的装饰器,它们用于为命令行工具定义参数。
argument() 装饰器:用于定义命令行的位置参数。位置参数是指在命令行中按照特定顺序提供的参数,不需要使用标志(如  或 )来指定。
option() 装饰器:用于定义命令行的选项。选项是可选的,并且通常使用标志(如  或 )来指定。常用参数包括:
  • default:指定选项的默认值;
  • prompt:若用户未提供选项,则交互式提示用户输入;
  • help:提供选项的帮助信息,当用户使用 –help 选项时会显示;
  • type:指定选项的类型,如 int, str, click.File() 等,默认为 str
  • required:指定选项是否为必需的,默认为 False
  • is_flag:指定选项是否为布尔选项;
  • multiple:允许选项多次使用,值合并为列表;
  • help:显示帮助文档中的描述文本,将会在 –help 中显示;
  • nargs:指定选项接受多个参数值;
示例代码:
### 文件名:ex_2.py ###

import click

@click.command()
@click.option(
    "--input",
    "-i",
    type=click.Path(exists=True),
    required=True,
    help="输入文件路径",
    metavar="FILE"
)
@click.option(
    "--verbose",
    "-v",
    is_flag=True,
    help="启用详细日志"
)
@click.option(
    "--sizes",
    multiple=True,
    type=int,
    default=[1],
    help="重复次数(可多次使用,如 --sizes 2 --sizes 3)"
)
def process(input, verbose, sizes):
    """读取文件内容,并根据 sizes 参数重复输出"""
    # 读取文件内容
    with open(input, "r") as f:
        content = f.read().strip()  # 去除首尾空白字符
    
    # 详细模式日志
    if verbose:
        click.echo(f"📂 文件路径: {input}")
        click.echo(f"📝 文件内容: {content}")
        click.echo(f"🔢 尺寸参数: {sizes}")
    
    # 结合 sizes 输出结果
    for size in sizes:
        combined = content * size
        click.echo(f"🔁 重复 {size} 次: {combined}")

if __name__ == "__main__":
    process()
将上述代码保存为 ex_2.py,然后在命令行中运行,后输出结果为:
>>> python ex_2.py -i demo.txt --sizes 2 --sizes 3 -v
📂 文件路径: demo.txt
📝 文件内容: Hello
🔢 尺寸参数: (2, 3)
🔁 重复 2 次: HelloHello
🔁 重复 3 次: HelloHelloHello


  • 3、添加互斥选项组:

Click中,可以通过自定义验证函数实现复杂的参数逻辑,例如互斥参数(即两个参数不能同时使用)。

示例代码:

### 文件名:ex_3.py ###

import click

# 定义一个函数用于验证互斥参数
def validate_mutex_args(ctx):
    """
    统一验证互斥参数。
    检查 --option1 和 --option2 是否同时被使用,如果同时使用则抛出错误。
    "
""
    if ctx.params.get("option1") and ctx.params.get("option2"):
        # 如果 option1 和 option2 同时被设置为 True,则抛出 UsageError
        raise click.UsageError("--option1 和 --option2 不能同时使用")

# 定义主命令 cli
@click.command()
@click.option(
    "--option1",
    is_flag=True,
    help="选项 1(不能与 --option2 同时使用)"
)
@click.option(
    "--option2",
    is_flag=True,
    help="选项 2(不能与 --option1 同时使用)"
)
@click.pass_context  # 将上下文对象 ctx 传递给函数
def cli(ctx, option1, option2):
    """
    演示互斥参数的命令行工具。
    通过 validate_mutex_args 函数验证互斥参数,并根据用户选择输出对应信息。
    "
""
    # 调用验证函数,检查互斥参数
    validate_mutex_args(ctx)

    # 根据用户选择的选项输出对应信息
    if option1:
        click.echo("选择了选项 1")
    elif option2:
        click.echo("选择了选项 2")
    else:
        click.echo("未选择任何选项")

# 入口点调用
if __name__ == "__main__":
    cli()

将上述代码保存为 ex_3.py,然后在命令行中运行,后输出结果为:

>>> python ex_3.py --option1
选择了选项 1

>>> python ex_3.py --option2
选择了选项 2

>>> python ex_3.py --option1 --option2
Usage: ex_3.py [OPTIONS]
Try 'ex_3.py --help' for help.

Error: --option1 和 --option2 不能同时使用


  • 4、多层级命令结构:

Click提供了分组命令 (@click.group()) 的功能,命令可以附加到类型为Group的其他命令上,这允许脚本任意嵌套。

示例代码:

### 文件名:ex_4.py ###

import click

# 定义一个 Click 命令组 cli
# 这是一个顶级命令组,用于组织其他子命令
@click.group()
def cli():
    pass

# 定义一个子命令 init
# 使用 @cli.command() 装饰器将 init 函数注册为 cli 的子命令
@cli.command()
@click.option("--name"help="指定要初始化的项目名称")
def init(name):
    """
    子命令 init 的实现。
    接收一个 --name 选项,用于指定项目名称。
    "
""
    click.echo(f"初始化项目: {name}")  # 打印初始化信息

# 定义另一个子命令 run
# 使用 @cli.command() 装饰器将 run 函数注册为 cli 的子命令
@cli.command()
@click.option("--debug", is_flag=True, help="启用调试模式")
def run(debug):
    """
    子命令 run 的实现。
    接收一个 --debug 选项,用于切换运行模式。
    "
""
    click.echo(f"运行模式: {'调试' if debug else '生产'}")  # 根据 debug 参数打印运行模式

# 入口点调用
# 当脚本直接运行时,调用 cli(),这会启动 Click 的命令行解析和执行
if __name__ == "__main__":
    cli()

将上述代码保存为 ex_4.py,然后在命令行中运行,后输出结果为:

>>> python ex_4.py init --name MyProject
初始化项目: MyProject

>>> python ex_4.py run --debug
运行模式: 调试


更多内容可以前往官方文档查看:

https://click.palletsprojects.com/en/stable/

本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments