首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Python argparse系统库全攻略:打造专业级CLI工具,效率暴涨

大家好,我是老K。

今天咱们来聊一个Python宝藏库,绝对能让你的命令行工具开发效率翻倍,甚至十倍不止! 啥库这么神? 就是 argparse

先问大家一个问题: 你是不是还在用 print() 和 input() 或者是 sys.argv 吭哧吭哧地写命令行脚本? 如果是的话,那可真得好好看看这篇文章了,因为你可能错过了Python世界里一个超级好用的轮子,一个能让你瞬间从“手工作坊”升级到“现代化工厂”的神器。

命令行工具的重要性,远超你的想象

别小看命令行工具(CLI,Command-Line Interface),它在程序员的世界里可是个老大哥。 想想Linux、Mac的终端,各种强大的命令是不是信手拈来? 好的CLI工具,效率高到飞起,能帮你快速完成各种任务:

自动化脚本: 定时任务、批量处理文件、服务器管理,这些都离不开CLI。

开发工具: 编译代码、运行测试、部署应用,很多开发流程都依赖CLI。

数据分析: 快速筛选数据、转换格式、执行分析,CLI也能派上大用场。

系统管理: 管理服务器、配置网络、监控资源,CLI更是运维人员的必备。

可以说,掌握CLI工具的开发,是程序员进阶的必经之路。 但是,如果用原始的方法去写,那真是又费劲又容易出错。 比如,参数解析就够你喝一壶的,各种参数类型、可选参数、必选参数、帮助信息,想想都头大。

这时候,argparse 就该闪亮登场了!

什么是 argparse ? 它凭啥这么牛?

简单来说,argparse 是Python官方标准库中用于解析命令行参数和选项的模块。 它的强大之处在于:

声明式语法,简洁高效: 你只需要告诉 argparse 你需要哪些参数,参数的类型、帮助信息等等,它就能自动帮你处理参数解析的各种细节,代码简洁到令人发指。

自动生成帮助信息: argparse 能根据你的参数定义,自动生成漂亮又实用的帮助信息,用户输入 -h 或 --help 就能看到,简直是用户友好性的典范。

强大的参数类型支持: argparse 支持各种参数类型,包括字符串、整数、浮点数、文件、布尔值等等,还能自定义参数类型,满足各种复杂需求。

灵活的参数组织方式: 支持位置参数、可选参数、子命令,可以构建非常复杂的命令行界面。

错误处理机制完善: 如果用户输入了错误的参数,argparse 会自动给出友好的错误提示,并引导用户正确使用。

总之,argparse 就是为了解放程序员的双手,让大家更专注于业务逻辑,而不是在烦琐的参数解析上浪费时间。

argparse 基础入门:三步搞定简单CLI

说了这么多,不如直接上手,用最简单的例子带你入门 argparse。

假设我们要写一个简单的脚本 greet.py,功能是根据用户输入的名字,打印一句问候语。

第一步: 导入 argparse 模块

import argparse

第二步: 创建 ArgumentParser 对象

parser = argparse.ArgumentParser(description='一个简单的问候程序')

ArgumentParser 是 argparse 的核心类,它负责创建参数解析器。 description 参数是程序的描述信息,会在帮助信息中显示。

第三步: 添加参数

parser.add_argument('name', help='你的名字')

add_argument() 方法用于添加参数。 这里我们添加了一个名为 name 的位置参数。 位置参数是必须输入的,并且位置很重要。 help 参数是参数的帮助信息。

第四步: 解析参数

args = parser.parse_args()

name = args.name

print(f'你好,{name}!')

parse_args() 方法会解析命令行参数,并将解析结果存储在一个 Namespace 对象中,赋值给 args 变量。 我们可以通过 args.参数名 的方式访问参数值。

完整代码 greet.py:

import argparse

parser = argparse.ArgumentParser(description='一个简单的问候程序')

parser.add_argument('name', help='你的名字')

args = parser.parse_args()

name = args.name

print(f'你好,{name}!')

运行脚本:

python greet.py 老K

输出:

你好,老K!

查看帮助信息:

python greet.py -h

输出:

usage: greet.py [-h] name

一个简单的问候程序

positional arguments:

name 你的名字

options:

-h, --help show this help message and exit

看,是不是超级简单? 几行代码就搞定了一个带参数解析和帮助信息的命令行工具。

进阶用法:可选参数、参数类型、默认值,让你的CLI更强大

上面的例子只是 argparse 的冰山一角,接下来我们看看更常用的功能。

1. 可选参数 (Optional Arguments)

可选参数不是必须输入的,通常用 - 或 -- 开头。 例如 -v 或 --verbose。

修改 greet.py,添加一个可选参数 -v 或 --verbose,用于控制是否输出详细信息。

import argparse

parser = argparse.ArgumentParser(description='一个简单的问候程序')

parser.add_argument('name', help='你的名字')

parser.add_argument('-v', '--verbose', action='store_true', help='显示详细信息') # 添加可选参数

args = parser.parse_args()

name = args.name

if args.verbose:

print(f'正在问候:{name}') # 详细信息

print(f'你好,{name}!')

解释:

'-v', '--verbose': 定义了短选项 -v 和长选项 --verbose。

action='store_true': 这是一个常用的 action,表示如果命令行中出现了 -v 或 --verbose,则 args.verbose 的值为 True,否则为 False。

运行测试:

python greet.py 老K

输出:

你好,老K!

python greet.py 老K -v

输出:

正在问候:老K

你好,老K!

2. 参数类型 (Type)

默认情况下,argparse 将所有参数都解析为字符串。 但我们可以通过 type 参数指定参数类型,例如 int,float,file 等。

修改 greet.py,添加一个可选参数 --age,要求输入整数年龄。

import argparse

parser = argparse.ArgumentParser(description='一个简单的问候程序')

parser.add_argument('name', help='你的名字')

parser.add_argument('-v', '--verbose', action='store_true', help='显示详细信息')

parser.add_argument('--age', type=int, help='你的年龄') # 指定参数类型为整数

args = parser.parse_args()

name = args.name

if args.verbose:

print(f'正在问候:{name}')

print(f'你好,{name}!')

if args.age:

print(f'你今年 {args.age} 岁了!') # 使用年龄参数

运行测试:

python greet.py 老K --age 35

输出:

你好,老K!

你今年 35 岁了!

如果输入非整数年龄,会报错:

python greet.py 老K --age abc

输出:

usage: greet.py [-h] [-v] [--age AGE] name

greet.py: error: argument --age: invalid int value: 'abc'

3. 默认值 (Default)

可以为可选参数设置默认值,如果用户没有输入该参数,则使用默认值。

修改 greet.py,为 --age 参数设置默认值 18。

import argparse

parser = argparse.ArgumentParser(description='一个简单的问候程序')

parser.add_argument('name', help='你的名字')

parser.add_argument('-v', '--verbose', action='store_true', help='显示详细信息')

parser.add_argument('--age', type=int, default=18, help='你的年龄 (默认为18岁)') # 设置默认值

args = parser.parse_args()

name = args.name

if args.verbose:

print(f'正在问候:{name}')

print(f'你好,{name}!')

print(f'你今年 {args.age} 岁了!') # 即使没有输入--age,也有默认值

运行测试:

python greet.py 老K

输出:

你好,老K!

你今年 18 岁了!

即使没有输入 --age 参数,程序也能正常运行,并使用了默认值 18。

高级技巧:子命令、互斥参数组、自定义Action,打造专业级CLI

argparse 的强大之处远不止于此,它还支持更高级的功能,让你可以构建非常复杂和专业的CLI工具。

1. 子命令 (Subparsers)

子命令可以将一个复杂的CLI工具分解成多个子命令,每个子命令有自己的参数和功能。 例如 git 命令,就有 git add、git commit、git push 等子命令。

假设我们要创建一个 tool.py 工具,包含两个子命令:add 和 remove。

import argparse

parser = argparse.ArgumentParser(description='一个多功能的工具')

# 创建子命令解析器

subparsers = parser.add_subparsers(title='子命令', dest='subcommand', help='可用的子命令')

# 创建 'add' 子命令解析器

parser_add = subparsers.add_parser('add', help='添加操作')

parser_add.add_argument('item', help='要添加的项')

# 创建 'remove' 子命令解析器

parser_remove = subparsers.add_parser('remove', help='移除操作')

parser_remove.add_argument('item', help='要移除的项')

args = parser.parse_args()

if args.subcommand == 'add':

print(f'执行添加操作,添加项:{args.item}')

elif args.subcommand == 'remove':

print(f'执行移除操作,移除项:{args.item}')

else:

parser.print_help() # 如果没有子命令,打印帮助信息

解释:

parser.add_subparsers(): 创建子命令解析器,dest='subcommand' 指定子命令的名称存储在 args.subcommand 中。

subparsers.add_parser('add', help='添加操作'): 创建名为 add 的子命令解析器。

parser_add.add_argument('item', help='要添加的项'): 为 add 子命令添加参数。

运行测试:

python tool.py add 文件1.txt

输出:

执行添加操作,添加项:文件1.txt

python tool.py remove 文件1.txt

输出:

执行移除操作,移除项:文件1.txt

python tool.py -h

输出:

usage: tool.py [-h] {add,remove} ...

一个多功能的工具

positional arguments:

{add,remove} 可用的子命令

add 添加操作

remove 移除操作

options:

-h, --help show this help message and exit

python tool.py add -h

输出:

usage: tool.py add [-h] item

positional arguments:

item 要添加的项

options:

-h, --help show this help message and exit

2. 互斥参数组 (Mutually Exclusive Groups)

互斥参数组可以确保一组参数中最多只能有一个被使用。 例如,一个程序可能允许用户选择输出格式为文本或JSON,但不能同时选择两种格式。

修改 tool.py,在 add 子命令中添加互斥参数组,允许用户选择输出格式为文本或JSON。

import argparse

parser = argparse.ArgumentParser(description='一个多功能的工具')

subparsers = parser.add_subparsers(title='子命令', dest='subcommand', help='可用的子命令')

parser_add = subparsers.add_parser('add', help='添加操作')

parser_add.add_argument('item', help='要添加的项')

# 创建互斥参数组

group = parser_add.add_mutually_exclusive_group()

group.add_argument('--text', action='store_true', help='以文本格式输出')

group.add_argument('--json', action='store_true', help='以JSON格式输出')

parser_remove = subparsers.add_parser('remove', help='移除操作')

parser_remove.add_argument('item', help='要移除的项')

args = parser.parse_args()

if args.subcommand == 'add':

output_format = 'text' if args.text else 'json' if args.json else '默认格式' # 判断输出格式

print(f'执行添加操作,添加项:{args.item},输出格式:{output_format}')

elif args.subcommand == 'remove':

print(f'执行移除操作,移除项:{args.item}')

else:

parser.print_help()

解释:

parser_add.add_mutually_exclusive_group(): 创建互斥参数组。

group.add_argument('--text', ...) 和 group.add_argument('--json', ...): 将 --text 和 --json 参数添加到互斥参数组中。

运行测试:

python tool.py add 文件1.txt --text

输出:

执行添加操作,添加项:文件1.txt,输出格式:text

python tool.py add 文件1.txt --json

输出:

执行添加操作,添加项:文件1.txt,输出格式:json

python tool.py add 文件1.txt --text --json

输出(报错):

usage: tool.py add [-h] [--text | --json] item

tool.py add: error: argument --json: not allowed with argument --text

可以看到,如果同时使用 --text 和 --json,argparse 会报错,保证了互斥性。

3. 自定义 Action (Custom Action)

argparse 提供了多种内置的 action,例如 store、store_true、append 等。 如果内置的 action 不够用,还可以自定义 action,实现更复杂的功能。

例如,我们可以自定义一个 action,用于验证输入的文件路径是否有效。

import argparse

import os

class ValidatePathAction(argparse.Action):

def __call__(self, parser, namespace, values, option_string=None):

filepath = values

if not os.path.exists(filepath):

parser.error(f'文件路径不存在: {filepath}')

setattr(namespace, self.dest, filepath)

parser = argparse.ArgumentParser(description='一个验证文件路径的工具')

parser.add_argument('filepath', action=ValidatePathAction, help='文件路径') # 使用自定义Action

args = parser.parse_args()

print(f'文件路径有效:{args.filepath}')

解释:

class ValidatePathAction(argparse.Action):: 定义一个自定义 Action 类,继承自 argparse.Action。

__call__(self, parser, namespace, values, option_string=None):: Action 的核心方法,用于处理参数值。

if not os.path.exists(filepath): parser.error(...): 验证文件路径是否存在,如果不存在则调用 parser.error() 报错。

setattr(namespace, self.dest, filepath): 将验证后的文件路径存储到 namespace 对象中。

action=ValidatePathAction: 在 add_argument() 中使用自定义 Action。

运行测试:

python tool.py /path/to/valid/file.txt

输出:

文件路径有效:/path/to/valid/file.txt

python tool.py /path/to/invalid/file.txt

输出(报错):

usage: tool.py [-h] filepath

tool.py: error: 文件路径不存在: /path/to/invalid/file.txt

实战案例:用 argparse 打造一个批量图片处理工具

说了这么多理论,不如来个实战案例,用 argparse 打造一个简单的批量图片处理工具,例如批量调整图片大小。

(简化版,仅作演示)

import argparse

from PIL import Image # 需要安装 Pillow 库: pip install Pillow

import os

def resize_image(image_path, output_dir, size):

try:

img = Image.open(image_path)

img_resized = img.resize(size)

filename = os.path.basename(image_path)

output_path = os.path.join(output_dir, f'resized_{filename}')

img_resized.save(output_path)

print(f'图片 {filename} 调整大小成功,保存到:{output_path}')

except Exception as e:

print(f'处理图片 {image_path} 失败:{e}')

parser = argparse.ArgumentParser(description='批量图片大小调整工具')

parser.add_argument('input_dir', help='输入图片目录')

parser.add_argument('output_dir', help='输出图片目录')

parser.add_argument('--size', type=int, nargs=2, default=[256, 256], help='调整后的图片尺寸 (宽度 高度),默认为 256x256')

args = parser.parse_args()

input_dir = args.input_dir

output_dir = args.output_dir

size = tuple(args.size) # 转换为元组

if not os.path.exists(output_dir):

os.makedirs(output_dir) # 创建输出目录

for filename in os.listdir(input_dir):

if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif')):

image_path = os.path.join(input_dir, filename)

resize_image(image_path, output_dir, size)

print('批量图片大小调整完成!')

运行测试:

假设有一个名为 images 的目录,里面放了一些图片。

python image_resizer.py images resized_images --size 512 512

这个命令会将 images 目录下的所有图片调整大小为 512x512,并保存到 resized_images 目录。

总结: argparse,你CLI工具开发的最佳搭档

argparse 作为Python标准库的一部分,功能强大且易于使用,绝对是你开发专业级命令行工具的最佳搭档。 掌握 argparse,你就能:

大幅提升CLI工具开发效率

构建更强大、更易用的命令行界面

提高代码可读性和可维护性

让你的Python技能更上一层楼

还在等什么? 赶紧行动起来,把 argparse 用到你的下一个Python项目中吧! 相信我,你会爱上它的。

最后,留个互动话题: 你平时在开发中,都用命令行工具做些什么呢? 有没有遇到过命令行参数解析的难题? 欢迎在评论区分享你的经验和想法,一起交流学习!

  • 发表于:
  • 原文链接https://page.om.qq.com/page/ODMVm-INlp96P9gYQvkio-cQ0
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券