如何在自动描述中设置argparse子命令顺序

How to set the argparse subcommand order in the automatic description

考虑以下代码:

$ cat a.py 
import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    subparsers = parser.add_subparsers()

    parser_a = subparsers.add_parser('a', help='A')
    parser_b = subparsers.add_parser('b', help='B')
    parser_c = subparsers.add_parser('c', help='C')

    args = parser.parse_args()

简单调用:

$ python a.py --help
usage: a.py [-h] {a,c,b} ...

positional arguments:
  {a,c,b}
    a         A
    b         B
    c         C

optional arguments:
  -h, --help  show this help message and exit

为什么位置参数被列为 {a,c,b} 而不是 {a,b,c},特别是我该如何解决这个问题?我有 6 个子命令,帮助看起来真的很难看。

这是 Python 2.7.7 FWIW。

你能显示(打印)吗,subparsers.choices?它应该是 OrderedDict.

{} 是从 subparsers.choices 属性生成的。虽然它可以是任何可迭代的东西(列表、字典等),但当前的 argparse 代码生成了一个 OrderedDict,它应该按照添加的顺序显示键。

我不知道这种行为有什么变化,至少在过去几年里没有。但我可以深入了解它的历史。

您可以通过给 subparsers 一个 metavar 值来更改显示,例如

subparsers = parser.add_subparsers(...., metavar='{a,b,c,d}')

http://bugs.python.org/issue9026

是将其设置为 OrderedDict 的错误修复。在 2011 年 3 月关闭。

好的,罪魁祸首是 setuptools,scoop. When installing the latter with its setup.py 它在 install_require 中请求 argparse>=1.1。下载并安装 arparse 1.2.1(这本身就很疯狂,因为在 PyPI 中有 1.2.21.3,除了 "system" argparse,它是 1.1 , 来自 python 2.7).

安装 argparse 1.2.1 后,出现我问题中描述的错误行为。并删除它,解决了问题。

我举报了the bug独家报道。