在 argparse 中自定义组间帮助

Customize help among groups in argparse

我正在使用 argparse 并且我有多个组,它们都有自己的选项集。

现在使用 --help 选项我不想默认显示所有选项。 --help 仅显示一组组选项。

应根据其他帮助选项显示其他组选项,如--help_1--help_2:

例如:

--help' to show Group 2 and 3
--help_1' to show Group 11 and 12
--help_2' to show Group 22 and 23

我知道我们可以使用 add_help=False 禁用默认 --help 选项,但我如何才能只显示选定的组特定帮助。

我们可以使用 _action_groups 属性从解析器中获取组列表,但它们不会公开任何 print_help( ) 选项本身。

我的示例代码:

parser = argparse.ArgumentParser(add_help=False)

parser.add_argument('--help_a', action='store_true')
parser.add_argument('--help_b', action='store_true')

group1 = parser.add_argument_group("Feature 1")
group1.add_argument('--foo1')
group2 = parser.add_argument_group("Feature 2")
group2.add_argument('--foo2')
group3 = parser.add_argument_group("Feature 3")
group3.add_argument('--foo3')

# TODO: --help_a to only print "Feature 1" groups help
# and --help_b to print Feature 2 and 3's help.

编辑:使用subparser并添加解析器(而不是组)将解决上述问题。但是subparser不适合我的情况,因为我一直在解析它,我只需要自定义帮助就可以显示。

我反对你正在尝试做的事情。

You are solving a problem that isn't yours to solve. return 使用信息是您脚本的工作。如果文本很多,这不是您的问题。你能做的事情,你正在做:将参数放入对用户有意义的组中。但是文字量不是数据结构的问题,而是数据表现的问题

其次,您将遵循 没有人使用的惯例。通常有

man command
command --help
command subcommand --help

其他任何东西都会让初次使用的用户感到困惑。

此外,如果您有很多参数组,人们总是需要咨询 --help 以找出他们接下来必须咨询哪个 --help_*当您可以立即在 --help 中展示它时,这可能会让用户感到沮丧

如果您使用多个帮助页面,您将防止重复使用您的帮助文本。搜索,例如:如果不手动切换,则无法搜索多个页面。

正确的做法 是通过像 less 这样的分页器传递文本。这允许用户逐页阅读文本、搜索(按 /)或将其保存到文件:

command --help | less

为了方便一些命令,比如git log,甚至检查output is an interactive terminal and automatically pass the output through less。这意味着

command --help > help.txt

将帮助保存到文件,而

command --help

分页显示帮助文本,并且可搜索。

所以我对 Windows 和 UNIX 的建议是

import os
import sys
import argparse
import subprocess


def less(data):
    if sys.stdout.isatty():
        if os.name == 'posix':
            cmd = "less"
        elif os.name == 'nt':
            cmd = "more" 

        process = subprocess.Popen([cmd], stdin=subprocess.PIPE)

        try:
            process.stdin.write(data)
            process.communicate()
        except IOError:
            pass
    else:
        print data


class MyArgumentParser(argparse.ArgumentParser):
    def print_help(self, file=None):
        less(self.format_help())
        self.exit()


parser = MyArgumentParser(prog='PROG')
group1 = parser.add_argument_group("Feature 1")
group1.add_argument('--foo1')
group2 = parser.add_argument_group("Feature 2")
group2.add_argument('--foo2')
group3 = parser.add_argument_group("Feature 3")
group3.add_argument('--foo3')
# parse some argument lists
print parser.parse_args()

这是自定义 format_help 方法:

import argparse

def format_help(self, groups=None):
    # self == parser
    formatter = self._get_formatter()

    # usage
    formatter.add_usage(self.usage, self._actions,
                        self._mutually_exclusive_groups)

    # description
    formatter.add_text(self.description)

    if groups is None:
        groups = self._action_groups

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

    # epilog
    formatter.add_text(self.epilog)

    # determine help from format above
    return formatter.format_help()

<your parser>

args = parser.parse_args()
# _action_groups[:2] are the default ones
if args.help_a:
    print(format_help(parser, [parser._action_groups[2]]))
    parser.exit()
if args.help_b:
    print(format_help(parser, parser._action_groups[3:]))
    parser.exit()

样本运行

1444:~/mypy$ python stack40718566.py --help_a
usage: stack40718566.py [-h] [--help_a] [--help_b] [--foo1 FOO1] [--foo2 FOO2]
                        [--foo3 FOO3]

Feature 1:
  --foo1 FOO1

1444:~/mypy$ python stack40718566.py --help_b
usage: stack40718566.py [-h] [--help_a] [--help_b] [--foo1 FOO1] [--foo2 FOO2]
                        [--foo3 FOO3]

Feature 2:
  --foo2 FOO2

Feature 3:
  --foo3 FOO3

所以它就像默认的 format_help,除了它需要一个 groups 参数。它甚至可以替换 ArgumentParser subclass.

中的默认方法

我们还可以创建一个自定义 Help 操作 class,其行为类似于标准帮助,只是它需要某种 group_list 参数。但是这个 post-解析操作更易于编码和测试。