如何用argparse优雅实现仅指定-a选项时才可使用-b选项的命令行参数处理?
如何用argparse优雅实现仅指定-a选项时才可使用-b选项的命令行参数处理?
我现在需要在Python脚本里处理一组命令行参数,要求的语法是:
tesy.py [-h] [-a [-b]]
(这只是个简化的示例,实际我的脚本还有不少其他参数)
简单来说,以下几种调用方式都是合法的:
test.py test.py -h test.py -a test.py -a -b
但下面这种调用是绝对不允许的:
test.py -b
因为-b必须在-a被指定的前提下才能使用。
我想知道,用argparse能不能优雅地实现这种参数约束?
首先我试了最直观的写法,但完全达不到要求:
from argparse import ArgumentParser parser = ArgumentParser(description='Test script') parser.add_argument('-a', action='store_true') parser.add_argument('-b', action='store_true') args = parser.parse_args()
因为这个写法会直接接受非法的test.py -b调用。
当然,我可以在解析完参数后手动做检查,当发现-b被指定但-a没被指定时抛出错误,代码是这样的:
from argparse import ArgumentParser parser = ArgumentParser(description='Test script') parser.add_argument('-a', action='store_true') parser.add_argument('-b', action='store_true') args = parser.parse_args() if args.b and not args.a: parser.error('Option -b requires option -a.')
但这种写法总觉得不够“优雅”,有没有办法让argparse本身就处理这种语法约束呢?
后来我还试了个取巧的写法(多亏了ChatGPT的提示):
from argparse import ArgumentParser parser = ArgumentParser(description='Test script') parser.add_argument('-a', action='store_true') args, unknown = parser.parse_known_args() if args.a: parser.add_argument('-b', action='store_true') args = parser.parse_args() else: args = parser.parse_args(unknown)
这个写法确实能正常工作,但有个致命问题:当用户输入test.py -h查看帮助文本时,完全看不到-b选项的存在。理论上我可以用ArgumentParser的usage=参数自定义帮助文本,但这实在太容易出错了——我的脚本参数很多还在迭代更新,手动维护帮助文本很容易遗漏修改。
另外,子解析器的方案也不适用,因为子解析器只针对位置参数,没法处理这种选项参数的依赖关系。
我也考虑过切换到docopt,但我的脚本已经完全基于argparse搭建好了命令行处理逻辑,不想全部重写。
所以想请教一下,有没有用argparse优雅实现这个需求的方法?还是说我只能退而求其次,用那些不够优雅的写法?
备注:内容来源于stack exchange,提问作者bontchev
相关产品推荐
相关产品推荐

