重新排序 Python argparse 参数组

Reorder Python argparse argument groups

我正在使用 argparse 并且我有一个自定义参数组 required arguments。有什么方法可以更改帮助消息中参数组的顺序吗?我认为在可选参数之前有必需的参数更合乎逻辑,但还没有找到任何文档或问题来提供帮助。

例如,改变这个:

usage: foo.py [-h] -i INPUT [-o OUTPUT]

Foo

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                      Output file name

required arguments:
  -i INPUT, --input INPUT
                      Input file name

对此:

usage: foo.py [-h] -i INPUT [-o OUTPUT]

Foo

required arguments:
  -i INPUT, --input INPUT
                      Input file name

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                      Output file name

(示例取自 this question

您可以考虑添加一个明确的可选参数组:

import argparse

parser = argparse.ArgumentParser(description='Foo', add_help=False)

required = parser.add_argument_group('required arguments')
required.add_argument('-i', '--input', help='Input file name', required=True)

optional = parser.add_argument_group('optional arguments')
optional.add_argument("-h", "--help", action="help", help="show this help message and exit")
optional.add_argument('-o', '--output', help='Output file name', default='stdout')

parser.parse_args(['-h'])

您可以将帮助操作移至您的可选组 此处描述: Move "help" to a different Argument Group in python argparse

如您所见,代码生成了所需的输出:

usage: code.py -i INPUT [-h] [-o OUTPUT]

Foo

required arguments:
  -i INPUT, --input INPUT
                        Input file name

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Output file name

解析器以 2 个参数组开始,通常是 positionaloptionals-h 帮助已添加到 optionals。当您执行 add_argument_group 时,将创建一个组(并返回给您)。它还附加到 parser._action_groups 列表。

当您寻求帮助时 (-h) parser.format_help() 被调用(您也可以在测试中这样做)。在 argparse.py 中寻找该方法。设置帮助消息,第一步是:

    # positionals, optionals and user-defined groups
    for action_group in self._action_groups:
        formatter.start_section(action_group.title)
        formatter.add_text(action_group.description)
        formatter.add_arguments(action_group._group_actions)
        formatter.end_section()

因此,如果我们重新排列 parser._action_groups 列表中的项目,我们将重新排列显示中的组。由于这是 _action_groups 的唯一用途,因此应该安全且容易。但是有些人不允许在幕后达到顶峰(查看或更改 ._ 属性)。

建议的解决方案是按照您希望看到的顺序创建您自己的组,并确保默认组为空(add_help=False 参数)。如果您坚持使用 public API,这是唯一的方法。

演示:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('foo')
g1 = parser.add_argument_group('REQUIRED')
g1.add_argument('--bar', required=True)
g1.add_argument('baz', nargs=2)

print(parser._action_groups)   
print([group.title for group in parser._action_groups])
print(parser.format_help())

parser._action_groups.reverse()  # easy inplace change
parser.print_help()

运行 结果:

1504:~/mypy$ python stack39047075.py 

_actions_group 列表和标题:

[<argparse._ArgumentGroup object at 0xb7247fac>,
 <argparse._ArgumentGroup object at 0xb7247f6c>,
 <argparse._ArgumentGroup object at 0xb721de0c>]
['positional arguments', 'optional arguments', 'REQUIRED']

默认帮助:

usage: stack39047075.py [-h] --bar BAR foo baz baz

positional arguments:
  foo

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

REQUIRED:
  --bar BAR
  baz

反向后:

usage: stack39047075.py [-h] --bar BAR foo baz baz

REQUIRED:
  --bar BAR
  baz

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

positional arguments:
  foo
1504:~/mypy$ 

实现它的另一种方法是使用新的 format_help 方法定义一个 ArgumentParser 子类。在该方法中,重新排序该 for action_group... 循环中使用的列表。

这确实是一个 hack,依赖于可变的内部实现,但在添加参数后,您可以简单地做:

parser._action_groups.reverse()

这将有效地使必需的参数组显示在可选参数组的上方。请注意,这个答案只是描述性的,而不是规定性的


来源: