Python argparse:"多个倍数"争论?

时间:2017-05-03 06:17:58

标签: python argparse

我想使用argparse在命令行上接收任意数量的 sets 位置参数。例如:

myapp.py show 1

show参数是"操作"并且1是"操作数"。

我希望能够接受多个操作集和操作数:

myapp.py show 1 test 2 write 3

我知道我可以添加nargs参数N作为最终参数的参数,以允许该参数的任意数量的重复。我希望做同样的事,但每次重复都有不止一个参数。

在这个例子中:

myapp.py show 1 test

应该无效,因为每个操作都必须带有一个操作数。

另外,假设所有操作数都是整数,所有运算符都是字符串:

myapp.py 1 show 2 test

应该失败,或者至少可以在代码中检测到,因此我可能会导致失败,因为操作员必须先来。

我也可能需要两个以上的参数"在不同项目中重复的一组参数,例如:

myapp.py test 1 outputFile.dat write 2 writeFile.dat

可以这样做吗?

2 个答案:

答案 0 :(得分:0)

扩展@mgilson给出的评论中的建议,这是一个以--为前缀的操作示例,这似乎有效:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs=2)
...
>>> parser.add_argument('--bar', nargs=2)
...
>>> args = parser.parse_args(('--foo', '1', 'out.dat', '--bar', '2', 'out.dat'))
>>> args
Namespace(bar=['2', 'out.dat'], foo=['1', 'out.dat'])

然后,您可以使用另一个argparser对每个子元素进行额外的解析:

>>> fooparser = argparse.ArgumentParser()
>>> fooparser.add_argument('num', type=int)
...
>>> fooparser.add_argument('fname')
...
>>> fooparser.parse_args(args.foo)
Namespace(fname='out.dat', num=1)

当然,如果第二个argparser失败了,你会得到一个非常奇怪的错误信息,所以你可能想要自己手动解析每个2-arg并产生你自己的错误信息。

答案 1 :(得分:0)

argv=sys.argv[1:]
adict = {k:int(v) for k,v in zip(argv[::2], argv[1::2])}

单词 - 从字典中的命令行收集字符串对。这也适用于来自nargs='*'位置或来自extras的{​​{1}}的未分化列表字符串。错误检查/陷印留给读者练习。

parse_known_args

或者,生成器方法可以让您更好地控制拆分和解析:

In [41]: argv='myapp.py show 1 test 2 write 3'.split()
In [42]: argv=argv[1:]
In [43]: adict = {k:int(v) for k,v in zip(argv[::2], argv[1::2])}
In [44]: adict
Out[44]: {'show': 1, 'test': 2, 'write': 3}