【问题标题】:Argparse: Optional arguments, distinct for different positional argumentsArgparse:可选参数,不同的位置参数不同
【发布时间】:2015-06-16 05:03:46
【问题描述】:

我想有一个带有可选参数的位置参数。喜欢my_command foo --version=0.1 baz bar --version=0.2。这应该解析成一个 args 列表 [foo, bar, baz] 并为其中的 2 个设置了 version

如果没有可选参数,设置nargs=*nargs=+ 很简单,但我正在努力为位置参数提供可选参数。 argparse 甚至可以吗?

【问题讨论】:

  • 您是否尝试过查看 argparse 的sub-commands?看起来它可能有效,但我不确定您是否可以将多个子命令放在单个解析器行上。
  • 我已经使用子解析器和组有一段时间了,但没有成功。看来,这两个选项的目标都与我的不同。我想知道我是否能够弯曲其中任何一个来满足我的需求。

标签: python command-line-arguments argparse


【解决方案1】:

Multiple invocation of the same subcommand in a single command line

这试图解析类似的东西

$ python test.py executeBuild --name foobar1 executeBuild --name foobar2 ....

两种提议的解决方案都会多次调用解析器。每个调用处理一个cmd --name value 对。一个事先拆分sys.argv,另一个使用argparse.REMAINDER 参数收集未解析的字符串。

通常选项可以以任何顺序出现。它们仅由 - 标志值标识。位置必须以特定的顺序出现,但可选项可能会出现在不同的位置之间。另请注意,在用法显示中,首先列出了可选项,然后是位置。

 usage: PROG [-h] [--version Version] [--other OTHER] FOO BAR BAZ

subparsers 是将位置参数与一个或多个 optionals 链接的唯一方法。但通常一个解析器只允许有一个子解析器参数。

没有子解析器,append 是从重复使用的可选选项中收集数据的唯一方法:

parser.add_argument('--version',action='append')
parser.add_argument('foo')
parser.add_argument('bar')
parser.add_argument('baz')

将处理您的输入字符串,生成如下命名空间:

namespace(version=['0.1','0.2'],foo='foo',bar='bar',baz='baz')

但是没有办法将baz 识别为“缺少”版本值的那个。

关于组 - 参数组只会影响帮助显示。它们与解析无关。

您将如何向您的用户(或 6 个月后的您自己)解释如何使用此界面?用法和帮助会是什么样子?将设计更改为更易于实现和解释的东西可能会更简单。


这是一个处理您的示例输入的脚本。

import argparse
usage = 'PROG [cmd [--version VERSION]]*'
parser = argparse.ArgumentParser(usage=usage)
parser.add_argument('cmd')
parser.add_argument('-v','--version')
parser.add_argument('rest', nargs=argparse.PARSER)
parser.print_usage()
myargv = 'foo --version=0.1 baz bar --version=0.2'.split()
# myargv = sys.argv[1:] # in production

myargv += ['quit']  # end loop flag
args = argparse.Namespace(rest=myargv)
collect = argparse.Namespace(cmd=[])
while True:
    args = parser.parse_args(args.rest)
    collect.cmd += [(args.cmd, args.version)]
    print(args)
    if args.rest[0]=='quit':
        break
print collect

它反复解析一个位置和可选,将其余部分收集在一个argparse.PARSER 参数中。这就像+,因为它至少需要一个字符串,但它也收集看起来像可选的字符串。我需要添加一个quit 字符串,这样当没有任何东西可以填充这个PARSER 参数时它不会抛出错误。

制作:

usage: PROG [cmd [--version VERSION]]*
Namespace(cmd='foo', rest=['baz', 'bar', '--version=0.2', 'quit'], version='0.1')
Namespace(cmd='baz', rest=['bar', '--version=0.2', 'quit'], version=None)
Namespace(cmd='bar', rest=['quit'], version='0.2')
Namespace(cmd=[('foo', '0.1'), ('baz', None), ('bar', '0.2')])

处理子解析器的位置参数也使用这个nargs 值。这就是它识别和收集cmd 字符串以及其他所有内容的方式。

所以可以解析你想要的参数字符串。但我不确定代码复杂性是否值得。代码也可能很脆弱,针对这组特定的参数进行了定制,并且只有几个变体。

【讨论】:

    猜你喜欢
    • 2011-05-27
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 2014-12-29
    • 1970-01-01
    相关资源
    最近更新 更多