我在SO上读过similar question,但这并没有解决我自己的问题。为了说明的目的,假设我有一个使用argpase
的Python程序,它提供了两个子命令:copy
和resume
:
prog copy src dest # src, dest positional, required
prog resume id # id positional, required
然而,最自然的方式来调用" copy"命令 NOT 显式给出copy
子命令,即我希望:
prog src dest
将执行默认的copy
操作,同时仍然保留两个子分析器的好处,每个子分析器处理一组不同的参数。是否可以使用argparse
包裹?
答案 0 :(得分:1)
正式没有。子命令参数是必需的位置参数,其中“choices”是子分析器名称(及其别名)。
这在帮助信息中很明显,{cmd1,cmd}
被显示为选项。
usage: ipython3 [-h] {cmd1,cmd2} ...
positional arguments:
{cmd1,cmd2}
optional arguments:
-h, --help show this help message and exit
最新的Python有一个'bug'实际上让它成为可选的。换句话说,如果你不给任何定位,它不会引发错误。这是一个错误,因为它改变了以前的行为,并且大多数人都需要它。但即使它是可选的,并且cmd1
被定义为默认值,它也不会在剩余的参数上运行cmd1
解析器。任何“位置”参数都将被视为错误的命令字符串。
我认为你能做的最好的事情就是定义一个或多个位置。一个人可能有选择和默认,并且是可选的(nargs ='?')。其余(或其他)可能有nargs='+'
。通过使用这些选项,您可以近似所需的行为,但它不会使用子分析器机制。
另一种思考问题的方法是考虑输入
prog one two
是否应将其解释为prog src dest
或prog cmd id
。说出它应该是前者的唯一依据是one
不是copy
或resume
中的一个。但在处理“选择”方面并不那么聪明。它根据位置分配一个值,然后测试它是否符合'choices'或'type'等标准(即整数,float v string)。