Python命令行工具Click

Python 命令行工具-Click

命令行工具click的编译指南,仓库地址:https://gitee.com/enzoism/python_cli

1-妇女之友-click

1-脚本代码

python 复制代码
import click  # 导入click库,用于创建命令行界面


@click.command()  # 使用click装饰器将函数标记为命令行命令
@click.argument("name")  # 定义位置参数name,用户必须提供
@click.option("-a", "--age", type=int, help="你的年龄")  # 定义可选参数age,类型为整数,并提供帮助信息
def greet(name, age):
    """一个简单的命令行工具"""
    click.echo(f"你好,{name}!")  # 使用click.echo输出问候语,比print更兼容
    if age:  # 如果提供了age参数
        click.echo(f"你今年{age}岁了。")  # 输出年龄信息


if __name__ == "__main__":  # 当脚本直接运行时执行
    greet()  # 调用greet函数启动命令行程序

2-直接测试

shell 复制代码
# 基本用法
(base) MacBook-Pro:python_setup_demo rong$ python click_simple.py 张三
你好,张三!

# 带可选参数
(base) MacBook-Pro:python_setup_demo rong$ python click_simple.py 张三 --age 25
你好,张三!
你今年25岁了。

# 查看帮助
(base) MacBook-Pro:python_setup_demo rong$ python click_simple.py --help
Usage: click_simple.py [OPTIONS] NAME

  一个简单的命令行工具

Options:
  -a, --age INTEGER  你的年龄
  --help             Show this message and exit.

3-安装测试

shell 复制代码
# 1-安装包
(base) MacBook-Pro:python_setup_demo rong$ pip install .
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Processing /Users/rong/Documents/EnzoApplication/WorkSpace/Python/20251222_Python_Setup/python_setup_demo02
  Preparing metadata (setup.py) ... done
Requirement already satisfied: click>=8.0.0 in /Applications/0ENZO/Installs/anaconda3/anaconda3/lib/python3.10/site-packages (from python-cli-examples==1.0.0) (8.0.4)
Requirement already satisfied: fire>=0.4.0 in /Applications/0ENZO/Installs/anaconda3/anaconda3/lib/python3.10/site-packages (from python-cli-examples==1.0.0) (0.7.1)
Requirement already satisfied: termcolor in /Applications/0ENZO/Installs/anaconda3/anaconda3/lib/python3.10/site-packages (from fire>=0.4.0->python-cli-examples==1.0.0) (3.2.0)
Building wheels for collected packages: python-cli-examples
  Building wheel for python-cli-examples (setup.py) ... done
  Created wheel for python-cli-examples: filename=python_cli_examples-1.0.0-py3-none-any.whl size=3088 sha256:1e38d417b4c61a60b3acf3ecc8babb938f239f182dbd9b86b67640089ab52861
  Stored in directory: /private/var/folders/kt/jy68vj1523dclg3py07q6zxc0000gn/T/pip-ephem-wheel-cache-5u7bw0u5/wheels/3d/19/5b/66b6bb4de747fb17d2199f8aa5945077a5084fa9a196f1092c
  Successfully built python-cli-examples
  Installing collected packages: python-cli-examples
  Successfully installed python-cli-examples-1.0.0

# 2-测试argparse命令
(base) MacBook-Pro:python_setup_demo rong$ argparse-demo 测试用户 --age 30 --city 上海
正在执行 argparse 示例程序...
你好,测试用户!
你今年30岁了。
你正值壮年!
你来自上海

# 3-测试click命令
(base) MacBook-Pro:python_setup_demo rong$ click-demo 张三 --age 25
你好,张三!
你今年25岁了。

# 4-验证两个命令都已安装
(base) MacBook-Pro:python_setup_demo rong$ which argparse-demo
/Applications/0ENZO/Installs/anaconda3/anaconda3/bin/argparse-demo
(base) MacBook-Pro:python_setup_demo rong$ which click-demo
/Applications/0ENZO/Installs/anaconda3/anaconda3/bin/click-demo

# 5-卸载包
(base) MacBook-Pro:python_setup_demo rong$ pip uninstall python-cli-examples
Found existing installation: python-cli-examples 1.0.0
Uninstalling python-cli-examples-1.0.0:
  Would remove:
    /Applications/0ENZO/Installs/anaconda3/anaconda3/bin/argparse-demo
    /Applications/0ENZO/Installs/anaconda3/anaconda3/bin/click-demo
    /Applications/0ENZO/Installs/anaconda3/anaconda3/lib/python3.10/site-packages/argparse_01_simple.py
    /Applications/0ENZO/Installs/anaconda3/anaconda3/lib/python3.10/site-packages/click_simple.py
    /Applications/0ENZO/Installs/anaconda3/anaconda3/lib/python3.10/site-packages/python_cli_examples-1.0.0.dist-info/*
Proceed (Y/n)? y
  Successfully uninstalled python-cli-examples-1.0.0

4-Click库优势

相比argparse,Click库具有以下优势:

  1. 装饰器语法:代码更简洁易读
  2. 类型提示:自动处理参数类型转换
  3. 帮助信息:自动生成完整的帮助文档
  4. 错误处理:内置更好的错误提示
  5. 可扩展性:支持子命令和复杂的应用结构

5-项目结构更新

复制代码
python_setup_demo02/
├── setup.py                 # 包配置文件(已更新支持两个工具)
├── argparse_01_simple.py   # argparse示例脚本
├── click_simple.py         # click示例脚本
└── BUILD_GUIDE.md          # 本编译指南(已更新)

6-支持的所有命令

安装后支持两个命令行工具:

  • argparse-demo: 基于argparse库的演示工具

    • 用法: argparse-demo <name> [options]
    • 支持: --age, --city, --verbose, --version
  • click-demo: 基于click库的演示工具

    • 用法: click-demo <name> [options]
    • 支持: --age

7-复杂示例

python 复制代码
#!/usr/bin/env python3
"""
click 示例脚本
演示如何使用 click 库创建优雅的命令行工具
"""

from datetime import datetime

import click


@click.group(invoke_without_command=True)
@click.pass_context
@click.option('--version', is_flag=True, help='显示版本信息')
def cli(ctx, version):
    """主CLI函数"""
    print("正在执行 click 示例程序...")
    """
    一个使用 click 创建的命令行工具示例

    这是一个功能强大的命令行工具,支持多个子命令。
    """
    if version:
        click.echo("click_example.py 版本 1.0.0")
        return

    if ctx.invoked_subcommand is None:
        click.echo(ctx.get_help())


@cli.command()
@click.argument('name')
@click.option('-a', '--age', type=int, help='你的年龄')
@click.option('-c', '--city', default='未知', help='你所在的城市')
@click.option('--verbose', is_flag=True, help='显示详细信息')
def greet(name, age, city, verbose):
    """
    向用户打招呼的命令

    NAME: 要问候的用户名字
    """
    click.echo(f"你好,{name}!")

    if age:
        click.echo(f"你今年{age}岁了。")

        # 使用 click 的颜色功能
        if age < 18:
            click.echo(click.style("你还是个未成年人士!", fg='yellow'))
        elif age < 30:
            click.echo(click.style("你正处于青壮年时期!", fg='green'))
        elif age < 50:
            click.echo(click.style("你正值壮年!", fg='blue'))
        else:
            click.echo(click.style("你已经步入中老年阶段!", fg='magenta'))

    click.echo(f"你来自{city}")

    if verbose:
        click.echo("\n--- 详细信息 ---")
        click.echo(f"当前时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        click.echo("感谢使用这个示例程序!")


@cli.command()
@click.option('--count', default=1, help='重复次数')
@click.option('--prefix', default='', help='前缀文本')
@click.argument('message')
def echo(count, prefix, message):
    """
    重复输出消息

    MESSAGE: 要重复输出的消息
    """
    for i in range(count):
        click.echo(f"{prefix}{message}")


@cli.command()
@click.option('--length', default=10, help='密码长度')
@click.option('--no-symbols', is_flag=True, help='不使用特殊字符')
def generate_password(length, no_symbols):
    """
    生成随机密码
    """
    import random
    import string

    chars = string.ascii_letters + string.digits
    if not no_symbols:
        chars += "!@#$%^&*"

    password = ''.join(random.choice(chars) for _ in range(length))

    click.echo(f"生成的密码: {click.style(password, fg='cyan', bold=True)}")
    click.echo(f"密码长度: {length}")
    click.echo(f"包含特殊字符: {'否' if no_symbols else '是'}")


@cli.command()
@click.argument('filename', type=click.Path(exists=True))
@click.option('--lines', default=10, help='显示的行数')
def tail_file(filename, lines):
    """
    显示文件的最后几行

    FILENAME: 要读取的文件路径
    """
    try:
        with open(filename, 'r', encoding='utf-8') as f:
            all_lines = f.readlines()
            last_lines = all_lines[-lines:] if len(all_lines) > lines else all_lines

            click.echo(f"\n文件 {click.style(filename, bold=True)} 的最后 {len(last_lines)} 行:")
            click.echo("-" * 50)

            for i, line in enumerate(last_lines, 1):
                click.echo(f"{i:3d}: {line.rstrip()}")

    except Exception as e:
        click.echo(click.style(f"错误: {e}", fg='red'), err=True)


if __name__ == '__main__':
    cli()

8-标注解释

@click.group

  • 用法@click.group(invoke_without_command=True) 用于定义一个命令组,它是一个可以包含多个子命令的容器。invoke_without_command=True 表示当没有指定子命令时,会调用该命令组对应的函数。
  • 示例 :在脚本中,cli 函数被装饰为一个命令组。当用户运行脚本时,如果没有指定子命令,就会执行 cli 函数中的代码,例如显示帮助信息等。

@click.pass_context

  • 用法@click.pass_context 用于将上下文对象传递给函数。上下文对象包含了命令行工具运行时的一些信息,如命令行参数、子命令等。
  • 示例 :在 cli 函数中,通过 @click.pass_context 装饰器,可以获取到上下文对象 ctx,进而可以使用 ctx.invoked_subcommand 来判断是否有子命令被调用,以及调用 ctx.get_help() 来获取帮助信息。

@click.option

  • 用法@click.option 用于定义命令行选项。它有多个参数,如:
    • --version:定义了一个名为 version 的选项,is_flag=True 表示这是一个布尔值选项,当指定该选项时,version 的值为 True,否则为 Falsehelp='显示版本信息' 提供了该选项的帮助信息。
    • -a--age:定义了一个名为 age 的选项,type=int 指定了该选项的值类型为整数,help='你的年龄' 提供了帮助信息。
    • -c--city:定义了一个名为 city 的选项,default='未知' 指定了默认值为 '未知'help='你所在的城市' 提供了帮助信息。
    • --verbose:定义了一个名为 verbose 的选项,is_flag=True 表示这是一个布尔值选项,help='显示详细信息' 提供了帮助信息。
    • --count:定义了一个名为 count 的选项,default=1 指定了默认值为 1help='重复次数' 提供了帮助信息。
    • --prefix:定义了一个名为 prefix 的选项,default='' 指定了默认值为空字符串,help='前缀文本' 提供了帮助信息。
    • --length:定义了一个名为 length 的选项,default=10 指定了默认值为 10help='密码长度' 提供了帮助信息。
    • --no-symbols:定义了一个名为 no_symbols 的选项,is_flag=True 表示这是一个布尔值选项,help='不使用特殊字符' 提供了帮助信息。
    • --lines:定义了一个名为 lines 的选项,default=10 指定了默认值为 10help='显示的行数' 提供了帮助信息。
  • 示例 :在各个命令函数中,通过 @click.option 装饰器定义了不同的选项,用户可以在命令行中通过指定这些选项来传递额外的参数,函数根据这些参数的值来执行相应的操作。

@click.argument

  • 用法@click.argument 用于定义命令行参数。它通常用于指定必须传递的参数。
  • 示例
    • greet 函数中,@click.argument('name') 定义了一个名为 name 的参数,表示用户必须在命令行中指定一个名字,否则会报错。
    • echo 函数中,@click.argument('message') 定义了一个名为 message 的参数,表示用户必须指定一个消息。
    • tail_file 函数中,@click.argument('filename', type=click.Path(exists=True)) 定义了一个名为 filename 的参数,并且通过 type=click.Path(exists=True) 指定了该参数的类型为路径,并且要求该路径必须存在。如果用户指定的路径不存在,会报错。

@click.command

  • 用法@click.command 用于定义一个命令。它将一个函数装饰为一个命令,该函数的名称将成为命令的名称。
  • 示例 :在脚本中,greetechogenerate_passwordtail_file 函数都被装饰为命令。用户可以通过指定命令的名称来调用这些函数,例如 click_example greetclick_example echo 等。

click.echo

  • 用法click.echo 用于在控制台输出文本。
  • 示例 :在脚本中,click.echo 被广泛用于输出各种信息,如问候语、密码、文件内容等。

click.style

  • 用法click.style 用于对文本进行样式化,例如设置颜色、加粗等。
  • 示例 :在脚本中,click.style 被用于给文本添加颜色,如 click.style("你还是个未成年人士!", fg='yellow') 将文本设置为黄色,click.style(password, fg='cyan', bold=True) 将密码文本设置为青色并加粗。

click.Path

  • 用法click.Path 用于定义路径类型的参数。它可以通过参数指定路径的一些约束条件,如是否存在、是否为文件或目录等。
  • 示例 :在 tail_file 函数中,type=click.Path(exists=True) 指定了 filename 参数的类型为路径,并且要求该路径必须存在。

相关推荐
宠..2 小时前
为单选按钮绑定事件
运维·服务器·开发语言·数据库·c++·qt·microsoft
那雨倾城2 小时前
用 YOLO Pose + Segmentation 在PiscCode构建“语义佛光”:一次实时视觉语义融合实验
图像处理·python·opencv·算法·yolo·计算机视觉·视觉检测
Lueeee.2 小时前
FFMPEG核心结构体
linux·ffmpeg
初九之潜龙勿用2 小时前
GMM NZ 全流程详解实战:FSDP MOE 训练加速
人工智能·pytorch·python
山土成旧客2 小时前
【Python学习打卡-Day28】类的蓝图:从模板到对象的构建艺术
linux·python·学习
咋吃都不胖lyh2 小时前
在任务管理器中筛选、查看进程
java·开发语言
宠..2 小时前
对单选按钮分组
开发语言·数据库·c++·qt·安全·安全性测试
怀旧,2 小时前
【Linux系统编程】14. 库使用与原理(上)
linux·运维·服务器
大学生资源网2 小时前
基于JavaWeb的邮件收发系统的设计与实现(源码+文档)
java·开发语言·spring boot·mysql·毕业设计·源码·课程设计