【发布时间】:2015-08-09 01:04:17
【问题描述】:
在我的 CLI 脚本中,我使用 argparse 来接收一些可选参数,然后是一个位置参数。位置参数用于确定要使用的子解析器,该子解析器又运行一个函数,该函数调用一个外部程序,该程序采用自己的参数。因此,命令行用法如下所示:
myscript [OPTIONS] subcommand [SUBCOMMAND_OPTIONS]
现在我的问题是我声明的 OPTIONS 与外部程序中声明的 SUBCOMMAND_OPTIONS 之间存在冲突。简单的解决方法是确保我重命名 myscript 中的所有冲突,但我不能对所有选项都这样做 - 最值得注意的是“-h”选项以获得帮助。理想情况下,我希望 argparse 在遇到子命令后立即停止解析,并将其余的 args 简单地传递给外部程序。
因此,以下调用应该显示 myscript 的帮助文本:
myscript -h
而相比之下,下面应该显示“bar”子解析器调用的外部程序的帮助文本:
myscript --foo bar -h
更多代码让上面的内容更清楚:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> subparsers = parser.add_subparsers()
>>> subparsers.add_parser("bar")
>>> parser.parse_known_args("--foo bar --test".split())
(Namespace(foo=True), ['--test'])
# cool - this is what I want, I'll just pass --test on to the external program
>>> parser.parse_known_args("--foo bar -h".split())
usage: bar [-h]
optional arguments:
-h, --help show this help message and exit
# unfortunately the above argparse help message is NOT what I wanted, instead I was looking for the result below:
(Namespace(foo=True), ['-h'])
>>> parser.parse_known_args("bar --test -- -h".split())
# this works, sort of, it requires educating the end-user to use the '--' parameter and I'd like to avoid that if possible.
(Namespace(foo=False), ['--test', '--', '-h'])
【问题讨论】:
-
你试过
argparse中的subparser机制吗?合身可能并不完美,但如果您阅读文档、尝试一下,然后再提出更多问题,这对我们所有人来说可能是最有成效的。 -
实际上我在上面的问题中明确提到了子解析器的使用,所以很明显我已经知道了。问题不是子解析命令的能力,而是遇到子命令后停止解析选项的能力。在你问我之前 - 是的,我已经在使用 argparse.parser_known_args() 来阻止 argparse 在它一无所知的外部命令参数上失败,问题在于 args 冲突 - 特别是。
-
--告诉它将后面的所有内容都视为位置参数,无论它们看起来是否像标志。nargs=argparse.PARSER和REMAINDEr也可用于获取位置的“其他所有内容”。子解析器机制使用PARSER来分配参数。试试这些,看看它们是否比完整的子解析器机制更适合您的需求。