如果没有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
时正确解析最后一行?
答案 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,并使用“ - ”来触发“消耗其他所有内容”操作。