【问题标题】:How to avoid args confusion with argparse?如何避免 args 与 argparse 混淆?
【发布时间】:2016-03-05 05:38:25
【问题描述】:

在一个名为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 示例),我应该如何指定模拟器列表?

【问题讨论】:

  • 你考虑过using docopt吗?
  • 我不确定,但可能你想要的是./simulate.py -s s1 s2 -- build
  • @Joost 不,从未听说过。我会看看它,如果可能的话,我更喜欢留在 argparse。
  • @AndreaCorbellini 这引发了另一个错误simulate.py: error: argument command: invalid choice: '--' (choose from 'build', 'run')
  • 这是一个已知问题 - 变量 nargs 标记的参数跟在位置之后。复杂的是这个位置是subparsers

标签: python argparse


【解决方案1】:

如解释:Argparse - do not catch positional arguments with `nargs`.

nargs='+'optional(标记参数)后跟positional 有问题。 optional 使用所有字符串,而 positional 则不使用任何字符串。有一个建议的错误补丁,但尚未发布。

正常的快速解决方案是使用'--' 来标记optional 及其参数的结尾。其他所有内容都被视为positionals。您还可以在两者之间放置一些其他标记的参数。

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

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

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

我找到了解释您的'--' 问题的代码。在将字符串转换为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 胆量,请随意查看链接的错误问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 2021-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    相关资源
    最近更新 更多