如何避免 args 与 argparse 混淆



在一个名为simulate.py的python脚本中,我有以下参数:

parser.add_argument('-s', '--simulators', nargs='+',
                     help='specify the simulators to use',
                     choices=['s1', 's2', 's3'])
parser_build = subparsers.add_parser('build')
parser_build.add_argument('-o3', '--optim', action='store_true')
parser_run = subparsers.add_parser('run')
parser_run.add_argument('-v', '--verbose', action='store_true')

以下命令行选项:

> ./simulate.py -s s1 s2 build

生成以下错误消息:

simulate.py: error: argument -s/--simulators: invalid choice: 'build'

在这种情况下,我应该如何指定模拟器列表,因为我有另一个没有选项前缀的参数(例如 -c 表示示例(?

如中所述:Argparse - 不要用"nargs"捕获位置参数。

nargs='+' optional(标记的参数(后跟一个positional有问题。 optional 消耗所有字符串,不为positional 留下任何字符串。 有一个建议的错误补丁,但尚未发布。

正常的快速解决方案是使用 '--' 来标记optional及其参数的结束。 其他一切都被视为positionals. 你也可以在两者之间放置一些其他标记的参数。

使你的情况复杂化的是-s会做出选择。 而positionalsubparsers,它也需要选择,['build', 'run']. 作为一个人,你理解"s2"是属于-s的选择,而"build"是解析器之一。 但argparse不会根据选择分配参数;它只使用计数(nargs(。 分配参数后检查choices

我必须查看代码以了解为什么'-s s1 s2 -- build'会引发子解析器选择错误。 通常忽略"--"。但显然subparsers没有这样做。 这是一个特殊的positional行动类。

====

=========================

我找到了解释您的'--'问题的代码。 在将字符串转换为type的函数中,有一个代码块:

    # for everything but PARSER, REMAINDER args, strip out first '--'
    if action.nargs not in [PARSER, REMAINDER]:
        try:
            arg_strings.remove('--')
        except ValueError:
            pass

您的subparsers参数具有nargs=PARSER,因此不会删除--

====

============================

我认为您需要更改-s以便它接受固定数量的参数。 或者定义一些其他optional,无论有用与否,都可以标记其结束。 如果您想深入了解argparse,请随意查看链接的错误问题。

最新更新