【问题标题】:python argparse: prefix or smart matching on sub parserspython argparse:子解析器上的前缀或智能匹配
【发布时间】:2017-09-19 19:07:30
【问题描述】:

是否可以在 python (2.7) argparse 中添加在指定执行哪个子命令时不需要完全匹配的子解析器?有谁知道如何做到这一点?它已经对长选项进行前缀匹配,例如--my-long-option 可以指定为 --my-l,只要它是所有其他选项中的唯一前缀即可。

例如,我想要一个类似的命令 foo apple foo banana foo carrot

我可以指定foo ap 来使用foo apple 子解析器。

如果我使用记录的方案添加这些子解析器,这不起作用,即

sub = parser.add_subparsers(help='commands')
apple = sub.add_parser( 'apple', ... )
banana = sub.add_parser( 'banana', ... )
carrot = sub.add_parser( 'carrot', ... )

这需要指定完整的子命令名称。

【问题讨论】:

  • 可以嵌套子解析器。你可以有一个foo 子解析器,它实际上有apple, banana, and carrot 子解析器。

标签: python command-line argparse


【解决方案1】:

正如您所注意到的,长选项与缩写一起使用。在最近的版本中,您可以使用 allow_abbrev=False 参数将其关闭。

子解析器名称使用不同的机制处理。对于主解析器,add_subparsers(...) 创建一个位置动作,带有 choices 参数。

您的 subparsers 命令大致相当于:

sp = parser.add_argument(dest='cmd', choices={'apple','banana', 'carrot'}, action=argparse._SubParsersAction, nargs='+...')

正是action 子类产生了独特的子解析器行为。

和普通的choices一样,测试是

astring in choices

要求完全匹配,没有任何特殊的缩写处理。

add_parser 中的“别名”参数可用于近似缩写。来自文档:

此外,add_parser 支持一个额外的别名参数,它允许多个字符串引用同一个子解析器。这个例子和 svn 一样,别名 co 作为 checkout 的简写:

之前有人提出了一个允许缩写的补丁。它是去年提交的,但后来因为有一些错误而撤回。

http://bugs.python.org/issue12713

我 [hpaulj] 建议关闭此问题,并依赖于子解析器缩写的别名。与“选择”的交互太复杂了,无法按照此处的建议进行处理。

【讨论】:

  • 这适用于 python 3.2+,但不幸的是不适用于 2.7.5。根据答案中给出的解释和代码演练,在 2.7.5 中无法做到这一点。
  • 看起来aliases 是在 2010 年通过bugs.python.org/issue9234 引入的,当时补丁 2.7 和 3+ 没有得到很好的协调。如果可能,当前系统会尝试将补丁应用于这两个版本。我怀疑当前的 3.+ add_parser 方法可能会被猴子修补到 2.7 文件中(或者可能是整个 _SubParsersAction 子类。我认为更改没有使用任何特殊的 3.5 功能。
猜你喜欢
  • 1970-01-01
  • 2018-12-31
  • 2021-03-15
  • 2013-12-21
  • 2013-10-07
  • 2020-12-04
  • 2011-11-20
  • 2016-02-27
相关资源
最近更新 更多