Python argparse 实战:用子命令、互斥参数和类型校验写一个像样的 CLI
Python argparse 实战:用子命令、互斥参数和类型校验写一个像样的 CLI写脚本时你多半这么读命令行参数:sys.argv[1]拿第一个,sys.argv[2]拿第二个。脚本小的时候没问题,一旦参数多起来、有可选项、有默认值,这套就崩了——参数顺序一错全乱,少传一个直接IndexError,想加个--help还得自己拼字符串。标准库的argparse就是干这个的。但很多人只会用它的皮毛(add_argument加几个位置参数),真正好用的子命令、互斥组、类型转换、自定义校验反而没碰过。这篇我们从一个实际需求出发,把它写成一个像样的命令行工具。需求:一个文件处理 CLI假设我们要做个工具filetool,支持两个子命令:filetool compress path --level 9—— 压缩文件filetool convert path --to png --quality 80—— 格式转换先看没有 argparse 会写成什么样:importsys# 朴素写法:脆弱、难维护cmdsys.argv[1]pathsys.argv[2]ifcmdcompress:levelint(sys.argv[3])iflen(sys.argv)3else6# ...参数一多,这里的sys.argv[3]会变成灾难:用户不按顺序传就错位,int()转换失败直接崩,没有任何友好提示。第一步:基础 parser 与类型校验importargparse parserargparse.ArgumentParser(progfiletool,description一个文件压缩与转换工具,)parser.add_argument(path,help要处理的文件路径,)parser.add_argument(--level,typeint,# argparse 自动转 int,转不了会报友好错误default6,choicesrange(1,10),# 限定 1-9,超范围自动拒绝help压缩级别 1-9(默认 6),)argsparser.parse_args()print(args.path,args.level)typeint让 argparse 自己做转换,用户传--level abc会得到error: argument --level: invalid int value: abc,而不是一个丑陋的 traceback。choices直接把合法值锁死,省了你手写if not 1 level 9。第二步:自定义校验——type 可以是任意函数type不只能填int、float,它接受任何「接收字符串、返回目标值」的可调用对象。想校验文件必须存在?写个函数塞进去:importargparsefrompathlibimportPathdefexisting_file(s:str)-Path:pPath(s)ifnotp.is_file():# 抛这个异常,argparse 会转成友好的命令行错误raiseargparse.ArgumentTypeError(f文件不存在:{s})returnp parserargparse.ArgumentParser(progfiletool)parser.add_argument(path,typeexisting_file,help要处理的文件)argsparser.parse_args()# args.path 此时已经是一个校验过的 Path 对象,不是 strprint(args.path.stat().st_size)关键点:校验失败要抛argparse.ArgumentTypeError,而不是ValueError或直接sys.exit。只有这个异常 argparse 才会包装成filetool: error: argument path: 文件不存在: xxx这种统一格式。返回值会直接成为args.path,类型都帮你转好了。第三步:互斥参数——两个开关不能同时出现比如转换时,--quiet(静默)和--verbose(啰嗦)逻辑上互斥,用户不该两个都传。用add_mutually_exclusive_group:groupparser.add_mutually_exclusive_group()group.add_argument(--quiet,actionstore_true,help静默模式)group.add_argument(--verbose,actionstore_true,help详细输出)用户同时传--quiet --verbose,argparse 直接报错:argument --verbose: not allowed with argument --quiet。这种约束靠自己写if很容易漏,交给互斥组一劳永逸。第四步:子命令——subparsers这是argparse最被低估的能力。git commit/git push这种「一个主命令带多个子命令、每个子命令有自己的参数」的结构,靠add_subparsers实现:importargparsefrompathlibimportPathdefexisting_file(s:str)-Path:pPath(s)ifnotp.is_file():raiseargparse.ArgumentTypeError(f文件不存在:{s})returnp parserargparse.ArgumentParser(progfiletool)# destcmd 让我们能从 args.cmd 读出用户选了哪个子命令subparsersparser.add_subparsers(destcmd,requiredTrue)# 子命令 1:compressp_compresssubparsers.add_parser(compress,help压缩文件)p_compress.add_argument(path,typeexisting_file)p_compress.add_argument(--level,typeint,default6,choicesrange(1,10))# 子命令 2:convertp_convertsubparsers.add_parser(convert,help格式转换)p_convert.add_argument(path,typeexisting_file)p_convert.add_argument(--to,requiredTrue,choices[png,jpg,webp])p_convert.add_argument(--quality,typeint,default80)argsparser.parse_args()requiredTrue保证用户必须选一个子命令,否则直接提示。注意每个子命令的参数是独立的:--level只属于compress,--to只属于convert,互不干扰。第五步:用 set_defaults 把子命令绑到处理函数拿到args.cmd后写一堆if args.cmd compress不够优雅。更干净的做法是给每个子命令绑一个处理函数:defdo_compress(args):print(f压缩{args.path},级别{args.level})defdo_convert(args):print(f把{args.path}转成{args.to},质量{args.quality})# 绑定:每个子命令关联一个 funcp_compress.set_defaults(funcdo_compress)p_convert.set_defaults(funcdo_convert)argsparser.parse_args()# 一行分发,不用 if-else 链args.func(args)set_defaults(func...)把处理函数塞进args,最后args.func(args)一行完成分发。加新子命令时只需add_parser 写个函数 set_defaults,主流程完全不用动——这就是可扩展的写法。完整可运行示例importargparsefrompathlibimportPathdefexisting_file(s:str)-Path:pPath(s)ifnotp.is_file():raiseargparse.ArgumentTypeError(f文件不存在:{s})returnpdefdo_compress(args):print(f压缩{args.path},级别{args.level})defdo_convert(args):mode静默ifargs.quietelse详细print(f把{args.path}转成{args.to},质量{args.quality},{mode}模式)defbuild_parser():parserargparse.ArgumentParser(progfiletool,description文件工具)subparser.add_subparsers(destcmd,requiredTrue)pcsub.add_parser(compress,help压缩文件)pc.add_argument(path,typeexisting_file)pc.add_argument(--level,typeint,default6,choicesrange(1,10))pc.set_defaults(funcdo_compress)pvsub.add_parser(convert,help格式转换)pv.add_argument(path,typeexisting_file)pv.add_argument(--to,requiredTrue,choices[png,jpg,webp])pv.add_argument(--quality,typeint,default80)gpv.add_mutually_exclusive_group()g.add_argument(--quiet,actionstore_true)g.add_argument(--verbose,actionstore_true)pv.set_defaults(funcdo_convert)returnparserif__name____main__:argsbuild_parser().parse_args()args.func(args)跑一下:$ python filetool.py convert ./a.png--towebp--quality90--verbose把 a.png 转成 webp,质量90,详细模式 $ python filetool.py--help# 自动生成的帮助$ python filetool.py convert--help# 子命令也有独立帮助小结别再手撸sys.argv[n],argparse 帮你搞定顺序、默认值、--help和错误提示。type接受任意「字符串进、目标值出」的函数,校验失败抛argparse.ArgumentTypeError才能得到友好错误。choices锁定合法值,add_mutually_exclusive_group声明互斥,把约束交给框架而不是手写 if。子命令用add_subparsers,每个子命令参数独立;set_defaults(func...)args.func(args)实现零 if-else 分发。一句话记忆:argparse 的正确用法不是「解析参数」,而是「声明式地描述你的命令行长什么样」,解析、校验、帮助、分发它全包了。

相关新闻

房地产项目三维建筑漫游动画:让客户“走进”未来的家

房地产项目三维建筑漫游动画:让客户“走进”未来的家

一、什么是房地产建筑漫游动画?房地产建筑漫游动画是将“虚拟现实”技术应用于楼盘展示的三维可视化表现形式。它把建筑设计师徒手勾画出的建筑方案、立面、剖面、透视图变成逼真的虚拟楼盘,让客户可随心所欲地漫游其中。与普通视频不同,建筑…

2026/8/3 21:57:21 阅读更多 →
Unity Input System消息传递机制详解:Send Messages、Unity Events与C# Events性能对比与选型指南

Unity Input System消息传递机制详解:Send Messages、Unity Events与C# Events性能对比与选型指南

1. 项目概述:为什么PlayerInput的消息传递值得深究? 在Unity的新版Input System中, PlayerInput 组件无疑是一个“明星”组件。它被设计为快速集成玩家输入逻辑的入口,官方文档和许多教程都会告诉你:拖上去&#xff…

2026/8/3 21:57:13 阅读更多 →
【独家首发|国家人社部未公开数据】:AI每渗透1%行业,中等技能岗位萎缩2.8%,但高适应性岗位增长11.3%——你的岗位在哪条曲线上?

【独家首发|国家人社部未公开数据】:AI每渗透1%行业,中等技能岗位萎缩2.8%,但高适应性岗位增长11.3%——你的岗位在哪条曲线上?

更多请点击: https://kaifayun.com 第一章:AI重塑就业结构的底层逻辑 人工智能并非简单替代人力,而是通过重构生产函数中的要素组合方式,从根本上改变劳动力在价值创造链条中的定位与权重。其底层逻辑植根于三个相互强化的机制&a…

2026/8/3 21:58:08 阅读更多 →

最新新闻

VLAN优先级、IP DSCP与Linux tc实战:构建端到端网络流量管控体系

VLAN优先级、IP DSCP与Linux tc实战:构建端到端网络流量管控体系

1. 项目概述:从网络拥堵到精准调控 干网络运维或者系统集成的兄弟,估计没少为网络卡顿、视频会议马赛克、核心业务被下载拖死这类破事头疼过。大家平时可能都听过QoS(服务质量)这个词,知道它大概是个“交通警察”&…

2026/8/3 21:57:31 阅读更多 →
为什么你的AI证据在庭审中被当庭排除?——2023全国276起AI证据驳回案例深度归因(含原始裁定书脱敏片段)

为什么你的AI证据在庭审中被当庭排除?——2023全国276起AI证据驳回案例深度归因(含原始裁定书脱敏片段)

更多请点击: https://intelliparadigm.com 第一章:AI证据的司法认定边界与法理根基 人工智能生成内容在诉讼中日益作为证据提交,但其可采性、真实性与证明力尚未形成统一的司法共识。法律对证据“三性”——客观性、关联性与合法性——的审查…

2026/8/3 21:57:31 阅读更多 →
建议收藏!2025最新38家国家一级科技查新机构全清单,含收费标准与加急办理通道

建议收藏!2025最新38家国家一级科技查新机构全清单,含收费标准与加急办理通道

相信所有需要开具科技查新报告的朋友们,每次在开之前最需要解决的问题就是去哪里开以及多少钱啦~ 这篇文章强烈建议大家收藏好啊!! 因为我会给大家分享2025最新38家国家一级科技查新机构的全清单, 也会给大家分享一…

2026/8/3 21:57:31 阅读更多 →
3分钟掌握FunASR情感识别模型部署:emotion2vec_plus_large完整实战指南

3分钟掌握FunASR情感识别模型部署:emotion2vec_plus_large完整实战指南

3分钟掌握FunASR情感识别模型部署:emotion2vec_plus_large完整实战指南 【免费下载链接】FunASR Open-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP s…

2026/8/3 21:57:31 阅读更多 →
如何用eSpeak NG构建多语言TTS系统:5个核心优势解析

如何用eSpeak NG构建多语言TTS系统:5个核心优势解析

如何用eSpeak NG构建多语言TTS系统:5个核心优势解析 【免费下载链接】espeak-ng eSpeak NG is an open source speech synthesizer that supports more than hundred languages and accents. 项目地址: https://gitcode.com/GitHub_Trending/es/espeak-ng 在…

2026/8/3 21:57:31 阅读更多 →
Android 13屏幕亮度调整:利用Overlay机制定制背光参数

Android 13屏幕亮度调整:利用Overlay机制定制背光参数

1. 项目背景与核心诉求 最近在折腾一台基于Android 13的设备,发现它的屏幕背光亮度调节范围不太理想。最低亮度在暗光环境下还是有点刺眼,而最高亮度在户外阳光下又感觉不够亮,看不太清。这其实是一个挺常见的问题,很多设备的默认…

2026/8/3 21:56:30 阅读更多 →

日新闻

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南

3个让你工作效率翻倍的Umi-OCR实战技巧:免费离线文字识别完全指南 【免费下载链接】Umi-OCR OCR software, free and offline. 开源、免费的离线OCR软件。支持截屏/批量导入图片,PDF文档识别,排除水印/页眉页脚,扫描/生成二维码。…

2026/8/3 0:00:47 阅读更多 →
[具身智能-181]:PC+服务器+具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构

[具身智能-181]:PC+服务器+具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构

PC服务器具身机器人:构建具身智能从仿真到量产的闭环迭代混合架构一、前言:具身智能需要“混合算力闭环系统”传统人工智能依赖云端静态数据集训练,不具备物理交互能力,无法适应真实世界的不确定性。具身智能(Embodied…

2026/8/3 0:00:47 阅读更多 →
[具身智能-181]:大分布式通信模型对比:看懂为什么 DDS 是 ROS2 底层通信最优解

[具身智能-181]:大分布式通信模型对比:看懂为什么 DDS 是 ROS2 底层通信最优解

前言构建机器人、具身智能这类分布式实时系统,通信底座直接决定整套系统的实时性、容错性、组网能力。分布式领域长期存在 4 类经典通信架构:点对点模式、Broker 中间代理模式、广播模式、以数据为中心(DDS)模式。很多开发者疑惑&…

2026/8/3 0:00:47 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/3 4:58:13 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/3 1:53:31 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/3 4:36:35 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/3 13:07:03 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/3 5:19:38 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/3 8:27:36 阅读更多 →