全面解析 Python 的CLI,轻松写 CLI

全面解析 Python 的CLI,轻松写 CLIPython 中编程 CLI 程序相对其他编程语言更加简单高效。本文试图快速讲解 Python 的 CLI 相关的库,能简单快速的写出cli 程序。

大家好,欢迎来到IT知识分享网。

全面解析 Python 的CLI,轻松写 CLI

Python 中编程 CLI 程序相对其他编程语言更加简单高效。本文试图快速讲解 Python 的 CLI 相关的库,能简单快速的写出cli 程序。

基础 CLI 能力

全面解析 Python 的CLI,轻松写 CLI

CLI 工具包含以下功能

  • 定义 CLI 命令
  • 传递参数可选项
  • 命令(成组)
  • 命令
  • 解析命令

Python 标准库 argsparse

全面解析 Python 的CLI,轻松写 CLI

argparse 是 Python 标准库中的一个模块,用于解析命令行参数。它功能强大,支持定义多个子命令、处理位置参数和可选参数、提供帮助信息等。

import argparse # 定义以 parse parse = argparse.ArgumentParser(description="第一个 python cli") # 添加参数 parse.add_argument("input", type=str, help="输入的文件") parse.add_argument("output", type=str, help="输出文件路径") # 添加可选参数 parse.add_argument("-v", "--verbose", action="store_true", help="显示详情") parse.add_argument("-t", "--type", choices=["json", "xml", "csv"], default="json", help="选择一个leixing") # 添加子命令 subparsers = parse.add_subparsers(dest="command") subparser_add = subparsers.add_parser("add", help="添加内容") # 子命令添加参数 subparser_add.add_argument('x', type=int, help='第一个数') subparser_add.add_argument('y', type=int, help='第二个数') subparser_remove = subparsers.add_parser("remove", help="删除内容") # 参数互斥组 group = parse.add_mutually_exclusive_group() # 互斥组添加参数 group.add_argument("--dry-run", action="store_true", help="执行前") group.add_argument("--force", action="store_true", help="强制") # 解析参数 args = parse.parse_args() # 输出参数对象内容 print(args, args.input, args.output, args.verbose, args.dry_run, args.force) print(f"result: {args.x + args.y}")

以上示例中,包含了 argparse 大部分功能使用,add_argument 函数事项相对复杂。可以根据 IDE 的提示参看参数类型和示例很好理解。

从 CLI 启动 FastAPI 服务

全面解析 Python 的CLI,轻松写 CLI

有时候我们的 web 服务从cli启动更加方便,以下是一个 fastapi 服务从 argparse 中启动的函数,我们可以扩展这个 cli 开启动不同的服务。

import argparse import uvicorn from app import app def main(): # 使用 argparse 解析命令行参数 parser = argparse.ArgumentParser(description="启动 FastAPI 服务") parser.add_argument("--host", type=str, default="127.0.0.1", help="服务主机地址") parser.add_argument("--port", type=int, default=8000, help="服务端口") parser.add_argument("--reload", action="store_true", help="是否启用热重载") args = parser.parse_args() # 使用 uvicorn 启动 FastAPI 应用 uvicorn.run(app, host=args.host, port=args.port, reload=args.reload) if __name__ == "__main__": main()

uvicorn 服务通过调用 run 方法与 cli 传递的参数结合,能够启动一个 uvicorn 服务,我们不用手动的敲 uvicorn 启动服务的命令。这样更加灵活,这阳服务成了 cli 的一个分支,可以扩展其它的能力。

argparse 对 CLI 功能其实已经够用了,但是它也自己的问题,它使用命令式的编程方式,虽然也可以抽象,但是社区已经做好了这些抽象的内容。Click 等等 cli 工具库就是这样一个功能强大的工具。

Python 三方库 Click

全面解析 Python 的CLI,轻松写 CLI

Click 是一个用于创建 CLI 应用程序的第三方库,Click 基于 Python 装饰器,设计简洁语法清晰,更易于使用和扩展。

与 argparse 相比,Click 提供了更高层次的 API,使得开发 CLI 程序更加直观。Click 在 args 基础上扩展了一些新的能力:装饰器定义命令、参数、可选项、以及上下文,同时还提供一些工具函数,例如颜色输出,错误处理等等。

  1. 安装 Click
pip install click
  1. 简单示例
import click @click.command() @click.argument('name') @click.option("--count", default=1, help="ge m times") def cli(name,count): click.echo(f"{name}{count}") if __name__ == '__main__': cli()

我们看到简单的装饰器,装饰一个 cli 函数就能实现命令,这样比命令式的代码更加实现和维护。但是有一点点学习成本。

  1. 命令成组
import click @click.group() def cli(): """命令行工具""" pass @cli.command() @click.argument('name') def greet(name): """问候命令""" click.echo(f'Hello, {name}!') @cli.command() @click.argument('number', type=int) def square(number): """计算平方""" click.echo(f'The square of {number} is {number ** 2}') if __name__ == '__main__': cli() # 函数名是命令子名字 # py group.py greet tom # py group.py square 123

使用 group 函数修饰一个 cli 函数,就能得到一个成组的命令行。对于多命令情况和适用。调用 cli 时需要传递不同的 args 和 options。值得注意的一点时组命令就是函数的名字。

4. 数据校验

Click也支持 options 数据校验,可以在定义的函数里面校验,也可以在 callback 中单独抽离出来校验,这里以后者为例:

import click def validate_age(ctx, param, value): if value < 0: raise click.BadParameter('Age must be non-negative.') return value @click.command() @click.option('--age', type=int, callback=validate_age, help='Your age') def age(age): """打印年龄""" click.echo(f'Your age is {age}') if __name__ == '__main__': age() 

当校验失败之后使用 raise 抛出 Click 的错误。当然也可以在修饰函数内部手动校验。

import click @click.command() @click.argument('number', type=int) @click.option("--name", prompt="Your name", help="The name to greet") def greet(number, name): if number < 0: raise click.BadParameter("Number must be non-negative") click.echo(f'Hello {name}! this is number {number}.') if __name__ == "__main__": greet()
  1. 上下文 context

不同的命令之间有时候需要共享数据,上下文就充当了这样的角色。在 Click 中实现一个上下文非常简单只需要使用 pass_context 装饰器即可:

import click @click.group() @click.pass_context def cli(ctx): """命令行工具""" ctx.obj = {'count': 1} @cli.command() @click.argument('name') @click.pass_context def greet(ctx, name): """问候命令""" count = ctx.obj['count'] for _ in range(count): click.echo(f'Hello, {name}!') @cli.command() @click.argument('count', type=int) @click.pass_context def set_count(ctx, count): """设置问候次数""" ctx.obj['count'] = count if __name__ == '__main__': cli() 

修改上下文就跟修改对象一样简单。

  1. 样式

由于命令行直接对终端中输入数据,cli 对终端样式也是支持的,你可以通过 style 函数控制终端输出的样式,一般包含:全景色、背景色、和加粗等等。

import click @click.command() def color_text(): """打印彩色文本""" click.echo(click.style('Hello, World!', fg='green', bg='black', bold=True)) if __name__ == '__main__': color_text() 

Python CLI 打包

全面解析 Python 的CLI,轻松写 CLI

pip install pyinstaller pyinstaller --onefile mycli.py

我们可以轻松使用 pyinstaller 将我们已经写好的 cli 程序打包成 exe 或者其他平台的可执行文件。这样我们就不需要每次都适用 python 运行了。经过尝试一个小的 args 命令行打包完成时 5M 如果对体积有要求,需要考虑体积问题。

Python CLI 链接

全面解析 Python 的CLI,轻松写 CLI

如果使用过 npm,npm 中 cli 时可以 link 到全局的。可以直接在全局适用 cli, 而不需要手动的在项目文件中夹中运行。Python 中如何实现了呢?在 Python 中有多种方式可以实现:

  • setuptools 与使用 pip install -e 实现符号链接)
  • 手动创建符号链接
  • 使用 pipx 进行全局安装

示例:

定义一个 mycli 入口文件:

import click @click.command() @click.argument('name') def cli(name): """简单的问候 CLI 工具""" click.echo(f'Hello, {name}!') if __name__ == '__main__': cli()

定义 setup.py 配置文件

from setuptools import setup, find_packages setup( name='mycli', version='0.1', packages=find_packages(), py_modules=['mycli'], install_requires=[ 'Click', ], entry_points=''' [console_scripts] mycli=mycli:cli ''', ) # mycli=mycli:cli 定义了命令 mycli,这个命令会在全局命令行中使用。 # 后面的 mycli:cli 是 Python 模块和函数的路径,这里的 mycli 是指 mycli.py 文件, # cli 是其中的一个函数。

构建与卸载

pip install -e . pip uninstall mycli

其他CLI 工具库

  • Typer: 与 Click 相似,特点是类型安全。风格与 FastAPI 类似。
  • docopt: 解析符合文档格式的命令行描述来生成解析逻辑。
  • cement:是一个高级命令行框架,适合构建功能复杂的 CLI 应用程序。它提供了许多内建功能,比如日志、配置管理、插件支持等。
  • Plumbum:是一个命令行工具库和进程库,它使得构建 CLI 工具更加灵活。

小结

不同的库各有优缺点,选择合适的库取决于你构建 CLI 工具的需求和个人偏好。如果你希望代码简单且不依赖额外库,可以选择 argparse, 而 Click 适合那些需要构建复杂命令行工具的开发者。

null

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/91068.html

(0)
上一篇 2024-10-19 12:00
下一篇 2024-10-19 12:45

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信