如何用nargs +和子命令

时间:2017-01-19 12:50:14

标签: python argparse

我正在尝试创建一个像

这样的命令
prog [-h] [-i ID [ID ...]] | -x [SOMETHING] 
     {cmd1,cmd2,cmd3}...

所以基本上在顶级我有一个解析器,它有一个用于-i和-x选项的互斥组,然后跟随那些(可能还有其他)选项,我有一个我想要运行的命令。每个命令都有自己的一组选项。我可以使用add_subparsers()使命令正常工作,但我遇到的问题是当我尝试向具有nargs='+'的根解析器添加参数时。当我这样做时,它会扼杀-i认为命令是参数而不是ID的所有参数。

有解决方法吗?看起来它必须查看-i查找命令字的参数,然后告诉argparse它应该在那时恢复解析。

1 个答案:

答案 0 :(得分:3)

我不得不多次阅读你的描述,但我认为这是问题所在:

prog -i id1 id2 cmd1 -foo 3 ....

它给出了一些关于找不到{cmd1,cmd2,cmd3}的警告。确切的错误可能有所不同,因为在某些版本中subparsers实际上并不需要。

在任何情况下,-i的参数都是['id1','id2','cmd1'],一切都是下一个-标志。对于主解析器,subparsers参数只是另一个positional参数(带choices)。将字符串分配给-i时,不检查字符串是否与cmds之一匹配。它只是看它是否以-开头。

在上下文中使用nargs='+'(或'*')的唯一方法是包含一些其他标记的参数,例如

prog -i id1 id2 -x 3 cmd1 --foo ...

我意识到这违反了您的mutually_exclusive群组。

基本点是非标志字符串是根据位置而不是值来分配的。对于变量nargs,您必须具有某种显式列表终止符。

从侧边栏

Argparse nargs="+" is eating positional argument

除了你的下一个位置是subparsers cmd之外,它是相似的。

==============

带有'+'的位置将在subparsers cmd之前正常工作

usage: prog [-h] foo [foo ...] {cmd1,cmd2} ...

In [160]: p1.parse_args('1 22 3 cmd1'.split())
Out[160]: Namespace(cmd='cmd1', foo=['1', '22', '3'])

但那是因为foocmd的字符串分配了一个regex模式测试。

usage: prog [-h] [--bar BAR [BAR ...]] {cmd1,cmd2} ...

字符串分配给bar,而不参考以下位置cmd的需要。如http://bugs.python.org/issue9338的建议修补程序所示,更改此行为不是一个微不足道的更改。它需要一个额外的前瞻试验和错误循环。