argparse.REMAINDER更改位置参数的行为

时间:2016-10-27 09:17:09

标签: python argparse

如果没有argparse.REMAINDER,可选参数可以位于位置参数之前或之后:

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-a')
parser.add_argument('b')

print(parser.parse_args('-a 1 2'.split()))  # Namespace(a='1', b='2')
print(parser.parse_args('2 -a 1'.split()))  # Namespace(a='1', b='2')

但是对于argparse.REMAINDER,可选参数必须在前面:

parser.add_argument('c', nargs=argparse.REMAINDER)

print(parser.parse_args('-a 1 2 3'.split()))  # Namespace(a='1', b='2', c=['3'])
print(parser.parse_args('2 -a 1 3'.split()))  # Namespace(a=None, b='2', c=['-a', '1', '3'])

如何在使用argparse.REMAINDER时正确解析最后一行?

2 个答案:

答案 0 :(得分:1)

来自文档:

  

argparse.REMAINDER。所有剩余的命令行参数都是   聚集到一个列表中。这通常对命令行很有用   调度到其他命令行实用程序的实用程序:

这意味着在接受这个参数之后,按定义使用余数不能有(任何)其他参数,因为它们是余数的一部分,并且会进入这个参数。

答案 1 :(得分:1)

要添加kabanus的答案,可能有助于了解一下如何解析参数。

迭代参数,首先寻找位置,然后是期权,然后是位置,......,

在位置步骤中,尝试使用nargs作为主要因素尽可能多地匹配。默认值是一个字符串('b'); '*'将匹配下一个可选项(-a);但REMAINDER忽略该约束并匹配结束。所以'位置'评估是贪婪的,而REMAINDER的评估尤其贪婪。

所以在'2 -a 1 3'情况下,初始'2'可以匹配'b',其余的可以匹配'c'。只有一个'位置'评估会消耗整个列表,包括'-a',它就完成了。

文档示例显示了这一点:

>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')

' - foo'作为可选项处理,但' - arg1'是REMAINDER的一部分。 'args'在'命令'后立即填充。

如果要保留对使用REMAINDER的控制权,请将其设为可选,add_argument('-c',nargs='...')。否则你将受到这个位置/选项循环的支配。

顺便说一句,subparsers使用narg=argarse.PARSER实现,这是'+ ...'的名称。它就像REMAINDER但需要至少一个字符串(subparser名称)。它也消耗了它的一切。

您可能希望使用“*”代替REMAINDER,并使用“ - ”来触发“消耗其他所有内容”操作。