Argparse:在“--help”中包含默认值的方法?

问题描述 投票:0回答:4

假设我有以下 argparse 片段:

diags.cmdln_parser.add_argument( '--scan-time',
                     action  = 'store',
                     nargs   = '?',
                     type    = int,
                     default = 5,
                     help    = "Wait SCAN-TIME seconds between status checks.")

目前,

--help
返回:

usage: connection_check.py [-h]
                             [--version] [--scan-time [SCAN_TIME]]

          Test the reliability/uptime of a connection.



optional arguments:
-h, --help            show this help message and exit
--version             show program's version number and exit
--scan-time [SCAN_TIME]
                    Wait SCAN-TIME seconds between status checks.

我更喜欢这样的东西:

--scan-time [SCAN_TIME]
                    Wait SCAN-TIME seconds between status checks.
                    (Default = 5)

查看帮助格式化程序代码,发现选项有限。有没有一种聪明的方法让

argparse
以类似的方式打印
--scan-time
的默认值,或者我应该将
help
格式化程序子类化?

python argparse
4个回答
655
投票

使用

argparse.ArgumentDefaultsHelpFormatter
格式化程序

parser = argparse.ArgumentParser(
    # ... other options ...
    formatter_class=argparse.ArgumentDefaultsHelpFormatter)

引用文档

另一个可用的格式化程序类,

ArgumentDefaultsHelpFormatter
,将添加有关每个参数的默认值的信息。

请注意,这仅适用于已定义帮助文本的参数;如果参数没有

help
值,则没有帮助消息来添加有关默认值 to 的信息。

扫描时间选项的确切输出将变为:

  --scan-time [SCAN_TIME]
                        Wait SCAN-TIME seconds between status checks.
                        (default: 5)

294
投票

'%(default)s'
添加到帮助参数以控制显示的内容。

parser.add_argument("--type", default="toto", choices=["toto","titi"],
                              help = "type (default: %(default)s)")

注释

  • 它是
    %
    + 括号中的默认值 + 格式字符(不要与我们在
    {default}
    或 f 字符串中找到的大括号
    format
    混淆)
  • 不要忘记在末尾添加类型表示的“说明符”(即
    s
    表示字符串、
    d
    表示整数、
    f
    表示浮点数等)
  • 您还可以添加常用的“printf”格式说明符(例如浮点数的位数、前导零等)

您可以参考printf文档了解更多详情。


22
投票

包装类

这是迄今为止我发现的最可靠、最干燥的方法,既可以显示默认值,又可以同时使用其他格式化程序,例如

argparse.RawTextHelpFormatter

#!/usr/bin/env python3

import argparse

class ArgumentParserWithDefaults(argparse.ArgumentParser):
    def add_argument(self, *args, help=None, default=None, **kwargs):
        if help is not None:
            kwargs['help'] = help
        if default is not None and args[0] != '-h':
            kwargs['default'] = default
            if help is not None:
                kwargs['help'] += ' Default: {}'.format(default)
        super().add_argument(*args, **kwargs)

parser = ArgumentParserWithDefaults(
    formatter_class=argparse.RawTextHelpFormatter
)
parser.add_argument('-a', default=13, help='''my help
for a''')
parser.add_argument('-b', default=42, help='''my help
for b''')
parser.add_argument('--no-default', help='''my help
for no-default''')
parser.add_argument('--no-help', default=101)

parser.print_help()
print()
print(parser.parse_args())

输出:

usage: main.py [-h] [-a A] [-b B] [--no-default NO_DEFAULT]
               [--no-help NO_HELP]

optional arguments:
  -h, --help            show this help message and exit
  -a A                  my help
                        for a Default: 13
  -b B                  my help
                        for b Default: 42
  --no-default NO_DEFAULT
                        my help
                        for no-default
  --no-help NO_HELP

Namespace(a=13, b=42, no_default=None, no_help=101)

ArgumentDefaultsHelpFormatter
+
RawTextHelpFormatter
多重继承

多重继承可以工作,但它似乎不是公共API:

#!/usr/bin/env python3

import argparse

class RawTextArgumentDefaultsHelpFormatter(
    argparse.ArgumentDefaultsHelpFormatter,
    argparse.RawTextHelpFormatter
):
    pass

parser = argparse.ArgumentParser(
    formatter_class=RawTextArgumentDefaultsHelpFormatter
)
parser.add_argument('-a', default=13, help='''my help
for a''')
parser.add_argument('-b', default=42, help='''my help
for b''')
parser.print_help()

输出:

usage: a.py [-h] [-a A] [-b B]

optional arguments:
  -h, --help  show this help message and exit
  -a A        my help
              for a (default: 13)
  -b B        my help
              for b (default: 42)

它之所以有效,是因为我们可以从源代码中简单地看到https://github.com/python/cpython/blob/v3.6.5/Lib/argparse.py#L648

  • RawTextHelpFormatter
    实现
    _split_lines
  • ArgumentDefaultsHelpFormatter
    实现
    _get_help_string

所以我们可以猜测他们会很好地合作。

但是,这似乎不是公共API,也不是

formatter_class
的方法,所以我认为目前没有公共API方法可以做到这一点。
argparse
文档字符串说:

该模块中的所有其他类都被视为实现细节。 (另请注意,HelpFormatter 和 RawDescriptionHelpFormatter 只是 被视为公共对象名称——格式化程序对象的 API 是 仍考虑实施细节。)

另请参阅:自定义 argparse 帮助消息

在 Python 3.6.5 上测试。


7
投票

能够自动在帮助输出中包含

default
值通常很有用,但仅限于那些显式指定的值(使用
default=..
)。已经提到的方法在这方面存在一些缺点:

  • ArgumentDefaultsHelpFormatter
    方法为未明确指定默认值的每个参数打印出
    (default: None)
    ,并为“标志”(
    (default: False)
    )打印出
    action='store_true'
    。这会使帮助输出变得混乱。为了避免这种情况,需要为每个此类参数手动添加
    default=argparse.SUPPRESS

  • '%(default)s'
    方法需要手动将其添加到我们想要在帮助中打印的所有参数的
    help
    字符串中。

  • 这两种方法最终都需要手动干预才能仅打印出“正确”的默认值。 自动执行此操作的一种方法是增强
ArgumentDefaultsHelpFormatter

以忽略

None
False
默认值:
class ExplicitDefaultsHelpFormatter(argparse.ArgumentDefaultsHelpFormatter):
    def _get_help_string(self, action):
        if action.default is None or action.default is False:
            return action.help
        return super()._get_help_string(action)

用它代替
ArgumentDefaultsHelpFormatter

parser = argparse.ArgumentParser(
        formatter_class=ExplicitDefaultsHelpFormatter
                )

这将仅打印帮助输出中明确设置的 
default

值。

注意:如果参数的默认值显式设置为 

None

False
,则该类的帮助中不会显示该参数;如果您希望在帮助输出中使用该参数,请将
%(default)s
字符串添加到
help
    

© www.soinside.com 2019 - 2024. All rights reserved.