使用位置参数指定默认子命令

Specify default subcommand with positional arguments

我已经阅读了关于 SO 的 similar question 问题,它没有解决我自己的问题。为了便于说明,假设我有一个使用 argpase 的 Python 程序,它提供了两个子命令:copyresume:

prog copy src dest  # src, dest positional, required
prog resume id      # id positional, required 

然而,调用 "copy" 命令最自然的方式是 NOT 显式地给出 copy 子命令,也就是说,我希望:

prog src dest

将执行默认的 copy 操作,同时仍然保留有两个子解析器的好处,每个子解析器处理一组不同的参数。 argparse 包可以吗?

正式没有。子命令参数是必需的位置参数,其中 '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 其余参数的解析器。并且任何 'positional' 参数都将被视为错误的命令字符串。

我认为您最多只能定义一个或多个位置。一个可能有选择和默认值,并且是可选的 (nargs='?')。其余(或其他)可能有 nargs='+'。通过使用这些选项,您可以接近所需的行为,但它不会使用子解析器机制。


考虑这个问题的另一种方法是考虑像

这样的输入
prog one two

它应该将其解释为 prog src dest 还是 prog cmd id。说它应该是前者的唯一依据是 one 不是 copyresume 之一。但它在处理 'choices' 时并不是那么聪明。它根据位置分配一个值,然后测试它是否满足 'choices' 或 'type' 等条件(即整数、浮点数 v 字符串)。