argparse模块 — 命令行参数解析

Python标准库精讲专题 · 操作系统接口篇 · 掌握命令行参数解析

专题:Python标准库精讲系统学习

关键词:Python, 标准库, argparse, 命令行参数, CLI, ArgumentParser, add_argument, 参数解析, 子命令

一、argparse模块概述

1.1 什么是argparse

argparse是Python标准库中用于编写命令行接口(CLI)程序的模块,自Python 2.7和Python 3.2起正式成为官方推荐的命令行参数解析方案。它取代了早期的getopt和optparse模块,提供了更强大、更易用的参数解析功能。无论是简单的脚本工具还是复杂的多命令应用程序(如git、docker),argparse都能优雅地处理参数定义、解析和帮助信息生成。

核心定位:让开发者只需定义程序需要接受哪些参数,argparse会自动处理从sys.argv中解析这些参数,并生成使用帮助和错误提示。

1.2 对比getopt和optparse的优势

在argparse出现之前,开发者主要使用getopt(模仿C语言getopt函数)和optparse(Python 2.3引入)来处理命令行参数。这两个模块存在明显的局限性:getopt功能过于底层,需要开发者手动处理大量逻辑;optparse虽然更高级,但对位置参数的支持非常有限,且已被官方宣布废弃。argparse在继承optparse设计思想的基础上,引入了位置参数、子命令、类型自动转换、可选值约束等现代CLI框架所必需的特性,同时提供了更加友好的错误消息和自动生成的帮助信息。

1.3 适用场景

argparse适用于几乎所有需要从命令行接收参数的Python程序,包括:数据处理脚本(指定输入输出文件路径)、自动化运维工具(控制运行模式、日志级别)、开发者工具(配置构建选项、测试开关)、机器学习训练脚本(设定超参数、数据集路径、GPU编号)以及任何需要从终端以非交互方式接收用户输入的应用程序。

官方推荐:argparse是Python标准库中处理命令行参数的首选方案。如果你的项目需要从命令行接收参数,优先考虑使用argparse而不是手动解析sys.argv。

二、ArgumentParser基础

2.1 创建参数解析器

使用argparse的第一步是创建ArgumentParser对象。构造函数接受多个参数来配置解析器的全局行为:description描述程序用途(显示在帮助信息开头)、epilog在帮助信息末尾追加内容、prog自定义程序名称(默认为sys.argv[0])、allow_abbrev是否允许参数缩写(默认True即允许)、add_help是否自动添加-h/--help选项(默认True)。

import argparse parser = argparse.ArgumentParser( prog='copy-tool', description='高效文件复制工具 — 支持通配符和增量备份', epilog='使用示例: copy-tool --verbose /src /dst', add_help=True )

2.2 添加参数

通过add_argument()方法定义程序需要接收的参数。该方法可以添加位置参数(通过参数名自动判断)和可选参数(以短横线开头)。每个参数可以指定类型、默认值、帮助描述、是否必需等众多属性。在Python 3.9+中,add_argument还支持参数的别名(aliases参数),让你可以为一个选项定义多个短名称。

parser.add_argument('input_file', help='输入文件路径') parser.add_argument('-o', '--output', help='输出文件路径(默认: output.txt)') parser.add_argument('-v', '--verbose', action='store_true', help='显示详细输出')

2.3 解析参数

parse_args()是核心解析方法,它会读取sys.argv(默认行为)或传入的字符串列表,按照add_argument的定义规则解析参数,并返回一个Namespace对象。Namespace对象将每个参数作为属性暴露,你可以通过点号语法直接访问。如果传入的参数不符合定义(如缺少必需参数、类型错误、未知参数),parse_args会自动打印错误信息并退出程序。

args = parser.parse_args(['data.txt', '-o', 'result.txt']) print(args.input_file) # 输出: data.txt print(args.output) # 输出: result.txt

2.4 使用parse_known_args处理未知参数

有时你的程序需要包装其他命令,参数量可能不确定。parse_known_args()方法在遇到未定义的参数时不会报错,而是返回一个包含已识别参数和剩余未知参数元组的二元组。这在编写包装器、中间件或需要透传参数的脚本时非常有用。剩余参数可以通过rest参数访问并传递给下游命令。

parser.add_argument('command', help='要执行的子命令') parser.add_argument('-v', '--verbose', action='store_true') args, rest = parser.parse_known_args(['run', '-v', '--extra', 'foo']) print(args.command) # 输出: run print(args.verbose) # 输出: True print(rest) # 输出: ['--extra', 'foo']

三、位置参数

3.1 位置参数的定义与特点

位置参数(Positional Arguments)是命令行中最基础的一种参数形式,它们依赖出现顺序而非选项名称来识别。与可选参数不同,位置参数不带短横线前缀,必须按照声明的顺序依次传入。位置参数默认是必需的(除非设置了nargs='?'),这使得它们非常适合于定义核心操作对象,如输入文件路径、目录名称、命令名称等。位置参数在帮助信息中被显示为usage行中的必填项。

parser = argparse.ArgumentParser(prog='img-convert') parser.add_argument('source', help='源文件路径') parser.add_argument('target', help='目标文件路径') parser.add_argument('format', help='输出格式(如 png, jpg)') args = parser.parse_args(['photo.png', 'photo.jpg', 'jpg']) print(f"从 {args.source} 转换为 {args.target},格式: {args.format}")

3.2 nargs参数数量控制

nargs参数允许一个位置参数接收多个命令行值,其取值有五种方式:N(接收恰好N个值,组成列表)、'?'(接收0个或1个值,与const/默认值配合使用)、'*'(接收任意数量,包括0个,组成列表)、'+'(接收至少1个,组成列表,否则报错)、argparse.REMAINDER(Python 3.10+支持更简洁方式,接收所有剩余参数,保持原样)。结合不同类型的nargs,可以构建出灵活的参数接受模式,例如可选输入文件列表、变长参数等。

parser = argparse.ArgumentParser(prog='sum-calc') parser.add_argument('numbers', nargs='+', type=int, help='要相加的数字') args = parser.parse_args(['1', '2', '3', '4', '5']) print(f"总和: {sum(args.numbers)}") # 输出: 总和: 15
# nargs='?' 的典型应用:支持默认值的可选位置参数 parser = argparse.ArgumentParser(prog='read-file') parser.add_argument('file', nargs='?', default='/etc/hosts', help='要读取的文件(默认: /etc/hosts)') args = parser.parse_args([]) print(f"读取文件: {args.file}") # 输出: 读取文件: /etc/hosts

3.3 type类型转换

位置参数的值默认以字符串形式保存,但通过type参数可以将其转换为任意Python类型。argparse会为每个传入的值调用type函数并在转换失败时自动抛出错误信息。常用的type值包括int、float、open(Python内置函数)以及自定义的转换函数。如果使用自定义类型函数,argparse会自动捕获ValueError并给出友好提示。

parser = argparse.ArgumentParser(prog='divide') parser.add_argument('dividend', type=float, help='被除数') parser.add_argument('divisor', type=float, help='除数') args = parser.parse_args(['10', '3']) print(f"结果: {args.dividend / args.divisor:.4f}") # 输出: 结果: 3.3333

四、可选参数

4.1 短选项与长选项

可选参数以单短横线(-)或双短横线(--)开头。短选项通常为单个字母(如-l、-f),方便快速输入;长选项则使用完整单词或短语(如--list、--file-path),更具可读性。argparse允许一个可选参数同时拥有短选项和长选项两种形式(如'-f', '--file'),在解析时它们被视为同一个参数。长选项的命名风格遵循POSIX惯例,使用连字符分隔单词。

parser = argparse.ArgumentParser(prog='logger') parser.add_argument('-l', '--level', default='INFO', help='日志级别(默认: INFO)') parser.add_argument('-f', '--file', help='日志输出文件(默认输出到控制台)') args = parser.parse_args(['-l', 'DEBUG', '-f', 'app.log']) print(f"日志级别: {args.level}") print(f"日志文件: {args.file}")

4.2 default默认值与required必需选项

default参数为未指定的可选参数提供默认值。当用户未传递该选项时,args对象将使用default值。required=True可以将通常可选的参数变为必需参数,用户必须显式提供否则解析器将报错退出。这在需要用户显式确认某些配置的场景中非常有用(如--config-file),可以防止遗漏重要配置。注意尽量不要滥用required,因为它违背了可选参数的本意。

parser = argparse.ArgumentParser(prog='deploy') parser.add_argument('--host', default='localhost', help='部署目标主机(默认: localhost)') parser.add_argument('--port', type=int, default=8080, help='端口(默认: 8080)') parser.add_argument('--api-key', required=True, help='API密钥(必填)') args = parser.parse_args(['--api-key', 'sk-12345']) print(f"目标: {args.host}:{args.port}")

4.3 choices可选值约束

choices参数将选项值限定在一个有限集合内,用户传入的值必须匹配集合中的某个元素。argparse会自动验证并在出错时打印所有可选值。choices接受任何可迭代类型(列表、元组、字典等),并支持类型敏感的匹配(传入集合匹配会同时检查值和类型)。通常搭配字符串、数字或枚举使用,特别适合限定运行模式、输出格式、日志级别等预定义选项。

parser = argparse.ArgumentParser(prog='backup') parser.add_argument('--mode', choices=['full', 'incremental', 'differential'], default='incremental', help='备份模式') parser.add_argument('--format', choices=['tar', 'zip', '7z'], default='tar', help='压缩格式') parser.add_argument('--compress-level', type=int, choices=range(0, 10), default=6, help='压缩级别 (0-9)') args = parser.parse_args(['--mode', 'full', '--format', 'zip']) print(f"备份模式: {args.mode},格式: {args.format}")

五、标志与动作

5.1 store_true与store_false布尔标志

store_true和store_false是最常用的action类型,用于实现布尔开关选项。store_true表示当选项出现时存储True,未出现时存储False;store_false则相反。这种模式广泛应用于verbose/quiet模式切换、force强制覆盖、dry-run模拟执行、recursive递归操作等场景。多个布尔标志可以组合使用,构建设置丰富的命令行工具。

parser = argparse.ArgumentParser(prog='clean') parser.add_argument('-v', '--verbose', action='store_true', help='显示详细输出') parser.add_argument('-f', '--force', action='store_true', help='强制删除,无需确认') parser.add_argument('--dry-run', action='store_true', help='模拟执行,不实际删除') parser.add_argument('-q', '--quiet', action='store_false', dest='verbose', help='静默模式(覆盖 -v)') args = parser.parse_args(['-vf']) print(f"详细输出: {args.verbose}") # True print(f"强制模式: {args.force}") # True print(f"模拟执行: {args.dry_run}") # False

5.2 store_const与append

store_const动作将预先设定的常数值存储到参数中,适用于需要根据选项映射到特定值的场景。append动作则允许同个选项多次出现,将每次的值收集到列表中,常用于指定多个输入文件、多个标签、多个过滤器等。当append与const配合使用时,可以实现无参数的重复标志(每次都添加同一个预设值)。对于需要顺序保持的场景,append按输入顺序保留值的次序。

# append 示例:允许多次指定输入文件 parser = argparse.ArgumentParser(prog='concat') parser.add_argument('--file', action='append', required=True, help='要合并的文件(可指定多次)') args = parser.parse_args(['--file', 'a.txt', '--file', 'b.txt', '--file', 'c.txt']) print(f"待合并文件: {args.file}") # 输出: 待合并文件: ['a.txt', 'b.txt', 'c.txt']

5.3 count计数模式

action='count'统计某个选项出现的次数,非常适合实现日志详细级别的递增控制(-v、-vv、-vvv)。每一次出现都会使计数器加1,未出现时默认值为0或None(可以通过default设置)。count模式简洁优雅地实现了多级详细输出,是Unix工具中常见的模式。注意结合type和choices可以对计数结果进一步约束。

parser = argparse.ArgumentParser(prog='find') parser.add_argument('-v', '--verbose', action='count', default=0, help='详细程度(使用 -v, -vv, -vvv)') args = parser.parse_args(['-vvv']) if args.verbose >= 3: print("DEBUG: 显示所有调试信息") elif args.verbose >= 2: print("INFO: 显示详细信息") elif args.verbose >= 1: print("WARN: 仅显示警告") # 输出: DEBUG: 显示所有调试信息

5.4 extend扩展列表(Python 3.8+)

Python 3.8引入了action='extend',与append不同,extend允许用户在一次选项中传入多个值(通过nargs配合),并将这些值合并到同一个列表中。而append是将每次出现当作单个元素添加。extend特别适合需要一次性指定多个值的场景,与nargs='+'或'*'配合使用效果最佳。

parser = argparse.ArgumentParser(prog='multi-cat') parser.add_argument('--include', action='extend', nargs='+', help='包含的文件模式(可指定多次,每次一个或多个)') args = parser.parse_args(['--include', '*.py', '*.js', '--include', '*.html']) print(args.include) # 输出: ['*.py', '*.js', '*.html']

六、类型与验证

6.1 基础类型转换

argparse的type参数支持所有可调用对象,包括Python内置类型。当设置type=int或type=float时,argparse会自动将字符串参数转换为对应的数值类型,并在转换失败时抛出清晰的错误信息。更强大的是,你可以使用type=open直接打开文件,argparse会处理文件打开操作,参数值直接变为文件对象。此外,type还可以接收自定义的可调用对象(函数或类),实现任意复杂度的类型转换逻辑。

parser = argparse.ArgumentParser(prog='calc') parser.add_argument('--rate', type=float, required=True, help='利率(如 0.05 表示 5%%)') parser.add_argument('--years', type=int, default=30, help='年限(整数,默认 30)') args = parser.parse_args(['--rate', '0.035', '--years', '15']) print(f"利率: {args.rate:.1%},年限: {args.years}") # 输出: 利率: 3.5%,年限: 15

6.2 FileType与文件参数

argparse.FileType是专门处理文件参数的类型工厂。它接受mode(读写模式,与open函数一致)、encoding(编码)、bufsize(缓冲区大小)等参数。使用FileType可以让argparse自动处理文件的打开操作,并在文件无法打开时打印友好的错误信息。解析完成后,参数值直接是可用的文件对象,配合with语句使用更加安全。FileType支持的模式包括'r'只读、'w'写入(会覆盖)、'a'追加、'x'排他写入等。

parser = argparse.ArgumentParser(prog='file-proc') parser.add_argument('input', type=argparse.FileType('r', encoding='utf-8'), help='输入文件') parser.add_argument('output', type=argparse.FileType('w', encoding='utf-8'), help='输出文件') args = parser.parse_args(['data.txt', 'output.txt']) content = args.input.read() args.output.write(content.upper()) args.input.close() args.output.close() print("文件处理完成!")

6.3 自定义类型函数

当内置类型无法满足需求时,可以编写自定义类型函数。argparse会在解析时为每个参数值调用该函数,如果函数抛出ValueError或TypeError,argparse会捕获异常并生成友好的错误消息,自动包含参数名称和异常信息。自定义类型函数可以实现:端口号范围验证、IP地址格式检查、文件路径扩展、颜色值解析(如#FF0000转RGB元组)、日期字符串解析等各种复杂逻辑。

def port_type(value): ivalue = int(value) if ivalue < 1 or ivalue > 65535: raise argparse.ArgumentTypeError( f"端口号 {value} 不在有效范围 (1-65535)") return ivalue def ip_type(value): parts = value.split('.') if len(parts) != 4: raise argparse.ArgumentTypeError(f"无效的IP地址: {value}") for p in parts: if not (0 <= int(p) <= 255): raise argparse.ArgumentTypeError(f"无效的IP地址: {value}") return value parser = argparse.ArgumentParser(prog='server') parser.add_argument('--host', type=ip_type, default='0.0.0.0', help='监听地址') parser.add_argument('--port', type=port_type, default=8080, help='监听端口 (1-65535)') args = parser.parse_args(['--host', '192.168.1.1', '--port', '3000']) print(f"服务器将在 {args.host}:{args.port} 启动")

七、子命令解析

7.1 子命令的概念与用途

子命令是现代命令行工具的标配,如git的commit、push、pull,docker的run、build、ps。set_subparsers()方法允许ArgumentParser拥有多个"子解析器",每个子解析器可定义自己独立的位置参数、可选参数和帮助信息。子命令系统让复杂的多操作CLI工具保持良好的组织结构和用户友好性,每个子命令都可以有自己的帮助页,通过prog属性清晰显示完整的命令路径。

parser = argparse.ArgumentParser(prog='todo', description='简单的待办事项管理工具') subparsers = parser.add_subparsers(dest='command', help='可用命令', required=True) # add 子命令 add_parser = subparsers.add_parser('add', help='添加新待办事项') add_parser.add_argument('title', help='待办事项标题') add_parser.add_argument('--priority', type=int, choices=[1, 2, 3], default=3, help='优先级 (1-高, 3-低)') # list 子命令 list_parser = subparsers.add_parser('list', help='列出待办事项') list_parser.add_argument('--all', action='store_true', help='显示所有(包括已完成)') list_parser.add_argument('--sort', choices=['time', 'priority'], default='time', help='排序方式') # done 子命令 done_parser = subparsers.add_parser('done', help='标记待办事项为已完成') done_parser.add_argument('task_id', type=int, help='任务ID') args = parser.parse_args(['add', '完成argparse学习', '--priority', '1']) print(f"命令: {args.command}") # 输出: 命令: add print(f"标题: {args.title}") # 输出: 标题: 完成argparse学习 print(f"优先级: {args.priority}") # 输出: 优先级: 1

7.2 子命令共享父解析器参数

在实际项目中,多个子命令往往需要共享一些公共参数(如全局调试开关、API地址、认证令牌等)。通过parents参数和父解析器(parent parser)机制,可以定义一组公共参数并让所有子命令继承。父解析器使用add_help=False避免产生重复的-h选项。变更父解析器会同步影响所有继承它的子命令,大大减少了重复代码和维护成本。

parent_parser = argparse.ArgumentParser(add_help=False) parent_parser.add_argument('--api-url', default='http://localhost:8000', help='API服务器地址') parent_parser.add_argument('--debug', action='store_true', help='开启调试模式') parser = argparse.ArgumentParser(prog='client', description='API客户端') subparsers = parser.add_subparsers(dest='command', required=True) get_parser = subparsers.add_parser('get', parents=[parent_parser], help='发送GET请求') get_parser.add_argument('endpoint', help='API端点路径') post_parser = subparsers.add_parser('post', parents=[parent_parser], help='发送POST请求') post_parser.add_argument('endpoint', help='API端点路径') post_parser.add_argument('--data', help='请求体JSON字符串') args = parser.parse_args(['get', '--api-url', 'https://api.example.com', 'users']) print(f"请求: GET {args.api_url}/{args.endpoint}") # 输出: 请求: GET https://api.example.com/users

7.3 嵌套子命令

argparse支持多级子命令嵌套,每个子解析器可以再拥有自己的子解析器,形成树状的命令结构。这种模式适合功能极度丰富的工具(如网络设备CLI、数据库管理工具)。每个级别的子命令都可以有自己的参数空间,通过dest参数指定的属性名逐级访问。设计嵌套子命令时需要保持层级清晰,一般不超过三级,过深的嵌套会损害可用性。

parser = argparse.ArgumentParser(prog='cloud') parser.add_argument('--region', default='us-east-1', help='云区域') svc_parser = parser.add_subparsers(dest='service', required=True) # 第一级子命令: compute compute = svc_parser.add_parser('compute', help='计算服务') compute_op = compute.add_subparsers(dest='action', required=True) compute_op.add_parser('list', help='列出实例') create_vm = compute_op.add_parser('create', help='创建实例') create_vm.add_argument('--type', default='t2.micro', help='实例类型') create_vm.add_argument('--count', type=int, default=1, help='数量') # 第一级子命令: storage storage = svc_parser.add_parser('storage', help='存储服务') storage_op = storage.add_subparsers(dest='action', required=True) storage_op.add_parser('list', help='列出存储桶') storage_op.add_parser('create', help='创建存储桶') args = parser.parse_args(['--region', 'cn-north-1', 'compute', 'create', '--type', 'g4dn.xlarge']) print(f"服务: {args.service},操作: {args.action}") print(f"区域: {args.region},类型: {args.type}") # 输出: 服务: compute,操作: create # 输出: 区域: cn-north-1,类型: g4dn.xlarge

八、高级特性与总结

8.1 互斥参数组

add_mutually_exclusive_group()创建的互斥组确保组内的参数最多只能出现一个(或者通过required=True强制必须出现恰好一个)。这在需要用户从多个互斥选项中选择的场景中非常有用,比如输出格式(--json / --xml / --yaml)、操作模式(--interactive / --batch / --daemon)。argparse会自动检查互斥约束,在用户同时使用冲突选项时打印清晰的错误信息。

parser = argparse.ArgumentParser(prog='export') group = parser.add_mutually_exclusive_group(required=True) group.add_argument('--json', action='store_true', help='导出为JSON格式') group.add_argument('--xml', action='store_true', help='导出为XML格式') group.add_argument('--csv', action='store_true', help='导出为CSV格式') parser.add_argument('--pretty', action='store_true', help='美化输出') parser.add_argument('--output', '-o', help='输出文件路径') # 互斥组确保以下两者只能选一 args = parser.parse_args(['--csv', '--pretty']) if args.json: print("导出格式: JSON") elif args.xml: print("导出格式: XML") elif args.csv: print("导出格式: CSV") print(f"美化输出: {args.pretty}") # 输出: 导出格式: CSV # 输出: 美化输出: True

8.2 互斥与条件约束的高级实现

argparse内置不支持条件依赖(如--format=json时必须同时指定--schema),但可以通过自定义Action或解析后手动验证来实现。常见的做法是在parse_args之后编写验证函数,检查参数间的依赖关系,发现不满足的条件时调用parser.error()输出友好错误信息。另一个方法是继承Action类,在__call__方法中记录参数出现的上下文,实现跨参数的状态验证。

parser = argparse.ArgumentParser(prog='upload') parser.add_argument('--format', choices=['json', 'xml', 'binary']) parser.add_argument('--schema', help='JSON Schema文件路径(JSON格式必填)') parser.add_argument('--compress-level', type=int, choices=range(0, 10)) args = parser.parse_args(['--format', 'json', '--schema', 'schema.json']) # 解析后验证条件依赖关系 if args.format == 'json' and not args.schema: parser.error('使用 JSON 格式时必须指定 --schema') if args.compress_level is not None and args.format == 'binary': parser.error('二进制格式不支持压缩') print("参数验证通过!")

8.3 帮助信息定制与格式化

argparse提供多种方式定制帮助信息的外观:通过add_help=False禁用默认-h并自定义帮助选项;使用RawDescriptionHelpFormatter保留description和epilog中的原始换行和缩进;使用RawTextHelpFormatter保留所有帮助文本的格式;通过metavar参数自定义usage和帮助中参数的显示名称;通过%(default)s在帮助文本中引用默认值;通过%(prog)s引用程序名称。Python 3.11+还支持argparse.BooleanOptionalAction简化布尔选项的定义。

parser = argparse.ArgumentParser( prog='app', formatter_class=argparse.RawDescriptionHelpFormatter, description='''\ 多行程序描述示例: 本程序支持以下特性: 1. 批量文件处理 2. 多线程并行 3. 增量备份与恢复''', epilog='更多信息请访问: https://example.com/docs' ) parser.add_argument('--threads', type=int, default=4, help='线程数量(默认: %(default)s)') parser.add_argument('--log-level', default='INFO', help='日志级别(默认: %(default)s)') parser.print_help()

8.4 set_defaults与参数后处理

set_defaults()方法可以在解析器级别设置参数默认值,通常用于为子命令绑定处理函数。常见的做法是先定义子命令解析器,然后通过set_defaults(func=handle_add)将每个子命令与一个处理函数关联。解析完成后通过args.func(args)即可调用对应的处理逻辑,实现命令模式的优雅分派。这种方式避免了大量的if-elif条件判断,代码更简洁、扩展性更强。

def handle_add(args): print(f"新增任务: {args.title} [优先级: {args.priority}]") def handle_list(args): print(f"列出所有任务 [排序方式: {args.sort}]") def handle_done(args): print(f"完成任务 #{args.task_id}") parser = argparse.ArgumentParser(prog='todo') sub = parser.add_subparsers(dest='command', required=True) add_p = sub.add_parser('add') add_p.add_argument('title') add_p.add_argument('--priority', type=int, default=3) add_p.set_defaults(func=handle_add) list_p = sub.add_parser('list') list_p.add_argument('--sort', default='time') list_p.set_defaults(func=handle_list) done_p = sub.add_parser('done') done_p.add_argument('task_id', type=int) done_p.set_defaults(func=handle_done) args = parser.parse_args(['add', '学习argparse', '--priority', '1']) args.func(args) # 输出: 新增任务: 学习argparse [优先级: 1]

核心要点总结:

1. argparse是Python官方推荐的命令行参数解析模块,替代了getopt和optparse。

2. 核心三要素:ArgumentParser创建解析器、add_argument定义参数、parse_args解析参数。

3. 位置参数按顺序解析并默认必需,可选参数以短横线开头并提供默认值。

4. action类型丰富:store_true/false(布尔开关)、append(收集列表)、count(计数)、extend(扩展列表)。

5. type参数支持内置类型转换和自定义验证函数,FileType自动管理文件打开。

6. 子命令通过add_subparsers实现多命令CLI工具,支持嵌套和参数继承。

7. 互斥组add_mutually_exclusive_group确保参数冲突检测,set_defaults实现命令分发。

8. 帮助信息可通过formatter_class和metavar等高阶选项深度定制。

使用建议:编写CLI程序时,建议统一使用argparse而非手动解析sys.argv。对于简单脚本,5-10行即可完成参数定义和解析;对于多命令工具,子命令配合set_defaults函数分派是业界最佳实践。