事先拆分sys.argv
是一个很好的解决方案。但它也可以在使用带有 的参数进行解析时完成nargs=argparse.REMAINDER
。这种类型的参数获取其余的字符串,无论它们是否看起来像标志。
parse_known_args
用以下代码替换:
...
build_parser.add_argument('rest', nargs=argparse.REMAINDER)
check_parser.add_argument('rest', nargs=argparse.REMAINDER)
extras = 'executeBuild --name foobar1 setupEnv executeBuild --name foobar2'.split()
# or extras = sys.argv[1:]
while extras:
args = main_parser.parse_args(extras)
extras = args.rest
delattr(args,'rest')
print args
# collect args as needed
印刷:
Namespace(build_name=['foobar1'], command='executeBuild')
Namespace(command='setupEnv')
Namespace(build_name=['foobar2'], command='executeBuild')
在文档中:
argparse.REMAINDER。所有剩余的命令行参数都被收集到一个列表中。这对于调度到其他命令行实用程序的命令行实用程序通常很有用:
一个问题REMAINDER
是它可能过于贪婪。http://bugs.python.org/issue14174。因此build_parser
,check_parser
不能有其他位置参数。
绕过贪婪的方法REMAINDER
是使用argparse.PARSER
. 这是使用的nargs
值subparsers
(未记录)。就像REMAINDER
,除了第一个字符串必须看起来像一个“参数”(没有“-”),并且匹配choices
(如果给定)。 PARSER
不像 贪婪REMAINDER
,因此子解析器可以有其他位置参数。
有一些额外的代码涉及“退出”字符串和虚拟解析器。这是为了解决这个PARSER
论点是“必需”的事实(有点像nargs='+'
)
from argparse import ArgumentParser, PARSER, SUPPRESS
main_parser = ArgumentParser(prog='MAIN')
parsers = {'exit': None}
main_parser.add_argument('rest',nargs=PARSER, choices=parsers)
build_parser = ArgumentParser(prog='BUILD')
parsers['executeBuild'] = build_parser
build_parser.add_argument('cmd')
build_parser.add_argument('--name', action='store', nargs=1, dest='build_name')
build_parser.add_argument('rest',nargs=PARSER, choices=parsers, help=SUPPRESS)
check_parser = ArgumentParser(prog='CHECK')
parsers['setupEnv'] = check_parser
check_parser.add_argument('cmd')
check_parser.add_argument('foo')
check_parser.add_argument('rest',nargs=PARSER, choices=parsers, help=SUPPRESS)
argv = sys.argv[1:]
if len(argv)==0:
argv = 'executeBuild --name foobar1 setupEnv foo executeBuild --name foobar2'.split()
argv.append('exit') # extra string to properly exit the loop
parser = main_parser
while parser:
args = parser.parse_args(argv)
argv = args.rest
delattr(args,'rest')
print(parser.prog, args)
parser = parsers.get(argv[0], None)
样本输出:
('MAIN', Namespace())
('BUILD', Namespace(build_name=['foobar1'], cmd='executeBuild'))
('CHECK', Namespace(cmd='setupEnv', foo='foo'))
('BUILD', Namespace(build_name=['foobar2'], cmd='executeBuild'))
另一种可能性是用于'--'
分隔命令块:
'executeBuild --name foobar1 -- setupEnv -- executeBuild --name foobar2'
但是有几个时会出现问题:http '--'
: //bugs.python.org/issue13922