Argparse,显示没有任何样板 argparse 文本的自定义帮助文本

Argparse, displaying custom help text without any of the boilerplate argparse text

看了十几个问题,我似乎找不到答案。

我有一个使用 argparse 编写的 python CLI。我有一个主命令,它只执行帮助文本和 4 个子命令。我的老板想要帮助文本的非常具体的输出。他让我把它写成一个文本文件,然后我们用那个文本文件来显示帮助文本。

但是,在某些情况下,它仍然会输出部分 argparse 帮助文本。

例如,如果我 运行 我的程序没有子命令,它只会从文件中输出我们的帮助文本。但是,如果我使用“-h”或“--help”,它将输出我们的帮助文本,然后是位置和可选参数列表以及其他 argparse 内容。我们不希望那样。

我可以使用“add_help=False”,但我们希望用户能够键入 -h 并仍然获得我们的帮助文本。如果我们将 add help 设置为 false,它将显示我们的帮助文本,后跟错误“-h not recognized”。

当用户在子命令后使用 -h 时,这样做也无济于事。我设置了 help=None 并将用法设置为我为每个子命令自定义的帮助文本,但它仍然在末尾显示样板 argparse 信息。

这就是我想要发生的事情:用户在没有子命令的情况下键入主命令会打印我的自定义帮助文本,仅此而已。用户键入主命令,没有子命令,然后是 -h/--help 并且它打印我的自定义帮助文本,没有其他内容。用户输入主命令,子命令之一,后跟 -h/--help ,它只输出我的帮助文本,没有其他任何内容。用户键入主命令、子命令,然后输入错误的参数或太多/太少的参数会显示我的帮助文本,而不会显示其他任何内容。基本上我只希望它不打印任何内容,或者只打印我的帮助文本。

我该怎么做?这是我的主要功能,其中解析器和子解析器都已配置:

def main():
    # Import help text from file
    p = Path(__file__).with_name("help.txt")
    with p.open() as file:
        help_text = file.read()

    # Configure the top level Parser
    parser = argparse.ArgumentParser(prog='myprog', description='My program', usage=help_text)
    subparsers = parser.add_subparsers()

    # Create Subparsers to give subcommands
    parser_one = subparsers.add_parser('subcommandone', prog='subcommandone', usage=help_text, help=None)
    parser_one.add_argument('arg1', type=str)
    parser_one.add_argument('-o', '--option1', default='mydefault', type=str)
    parser_two= subparsers.add_parser('subcommandtwo', usage=help_text, help=None, prog='subcommandtwo')
    parser_three= subparsers.add_parser('subcommandthree', usage=help_text, help=None, prog='subcommandthree')
    parser_four= subparsers.add_parser('subcommandfour', usage=help_text, help=None, prog='subcommandfour')

    # Assign subparsers to their respective functions
    parser_one.set_defaults(func=functionone)
    parser_two.set_defaults(func=functiontwo)
    parser_three.set_defaults(func=functionthree)
    parser_four.set_defaults(func=functionfour)
    parser.set_defaults(func=base_case)

    # Parse the arguments and call appropriate functions
    args = parser.parse_args()
    if len(sys.argv) == 1:
        args.func(args, parser)
    else:
        args.func(args)

有什么想法吗?

您可以在帮助文本显示后、解析开始前使用 sys.exit(),以避免出现 "-h not recognized".[ 的问题。 =16=]

所以行之前的任何地方

# Parse the arguments and call appropriate functions

添加

if len(sys.argv) == 1 or '-h' in sys.argv or '--help' in sys.argv:
    print(help_text)
    sys.exit(1)

如果这还不够好,您可以像这样子类化 argparse.HelpFormatter

usage_help_str = 'myscript command [options]'
epilog_str = "More info can be found at https://..."

class Formatter(argparse.HelpFormatter):
    # override methods and stuff

def formatter(prog):
    return Formatter(prog)

parser = argparse.ArgumentParser(formatter_class=formatter, epilog=epilog_str, usage=usage_help_str, add_help=False)

我试着四处寻找关于子类化 helpFormatter 的文档,但我找不到任何东西。看起来 looking at the source code 想弄清楚如何对其进行子类化。