Argparse: '--help'にデフォルト値を含める方法?


307

次の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フォーマッタをサブクラス化するだけですか?


5
docoptに興味があるかもしれません。私は再びargparseを見たことがありません。
Paulo Scardine、2012

14
@PauloScardine-言語に組み込まれていることは、argparseの主な利点です。
ヨルダン2012

1
@PauloScardine:非標準のライブラリを現在のプロジェクトに取り込むのは確かに面倒ですが、docoptの出力の外観が気に入っています。先端をありがとう!
JS。

@JS。「非標準のライブラリを現在のプロジェクトに引き込むのは本当に大変だ」とあなたは言う pypiには非常に便利なライブラリがたくさんあります。私のコンテキストでは、非標準のライブラリを取り込むのは簡単です。あなたの文脈で難しいとしたら、それは悲しいことです。
guettli

3
@guettli:そのプロジェクトは商用組み込みプロジェクト用でした。インストールは簡単でしたね。企業の法務から承認を得ることは悪夢でした。
JS。

回答:


447

argparse.ArgumentDefaultsHelpFormatterフォーマッタを使用します。

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

ドキュメントを引用するには:

利用可能な他のフォーマッタクラスArgumentDefaultsHelpFormatterは、各引数のデフォルト値に関する情報を追加します。

これは、ヘルプテキストが定義されている引数にのみ適用されることに注意してください。なしでhelp引数の値、デフォルト値に関する情報を追加するヘルプメッセージはありません

スキャン時間オプションの正確な出力は、次のようになります。

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

12
明示的な引数のみdefault=がデフォルト値を表示するように制御できますか?「デフォルト:なし」のテキストは好きではないので。
ziyuang

14
あなたは、設定することができますdefaultSUPPRESSdefault=argparse.SUPPRESS。なお、引数が省略された場合は、その場合には何の属性は、名前空間の結果に追加されないことを、参照マニュアルを参照してdefault
Martijn Pieters

4
作成された各サブパーサーにもこれを指定する必要があることに注意してください。
KomodoDave 2014年

1
次に、問題を示す最小限の再現可能な例を含めて、新しい質問を作成します。言ったように、Python 2.7で動作します。
Martijn Pieters

3
@David私も同じ問題を抱えていました。help引数を追加するadd_argumentと、動作するはずです。
PabloDíazOgni

190

'%(default)s'表示内容を制御するには、ヘルプパラメータに追加します。

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

9
このオプションが気に入ったのは、すでにformat_class = argparse.RawTestHelpFormatterを使用していて、OOPを使って遠回りしたくなかったからです。
mqsoh 2013年

23
変数「type」をフォーマット文字列に含めることを忘れないでください。たとえば、文字列の場合は「%(default)s」、数字の場合は「%(default)d」です。
strongMA 2014年

1
このソリューションの方がはるかに優れており、はるかに簡単です。デフォルト値のない引数を明示的に処理する必要はありません。
void.pointer 2018

@mqsoh多重継承は、実際には働いていたが、残念ながら公開APIはありません:stackoverflow.com/a/52025430/895245
チロSantilli郝海东冠状病六四事件法轮功

1
フォーマッタクラスを変更すると、あらゆる場所に "(デフォルト:なし)"の束が追加され、ヘルプが煩雑になるため、これが好きです。
6005

11

ラッパークラス

これは、デフォルトを表示argparse.RawTextHelpFormatterし、同時に次のような別のフォーマッターを使用するためにこれまでに見つけた中で最も信頼性が高く、DRYのアプローチです。

#!/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を使用する方法はないと思います。argparsedocstringさんのコメント:

このモジュールの他のすべてのクラスは、実装の詳細と見なされます。(また、HelpFormatterとRawDescriptionHelpFormatterはオブジェクト名としてのみパブリックと見なされることに注意してください。フォーマッタオブジェクトのAPIは実装の詳細と見なされます。)

参照:argparseヘルプメッセージのカスタマイズ

Python 3.6.5でテスト済み。


1
すごい !最後に、フォーマットされたdocstringとデフォルトの引数の両方を出力します。ありがとう
シルヴァン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.