18

私はArgparseを使用してコマンドラインユーティリティを作成しており、一連のsub_parsers(サブコマンド)を追加しました。ヘルプメニューでは、それらは「コマンド」と呼ばれるグループの下に表示され、すべての可能なオプションの素晴らしいリストが表示されます。ただし、このリストが表示される前は、同じコマンドがすべてグループタイトルの下に中かっこで囲まれて表示されます。

Commands:
    {foo, bar}

    foo          - foo does foo
    bar          - bar does bar

中かっこで囲まれた冗長なエントリを削除したいと思います。sub_parsersで満たされたこのグループにのみ表示されます。

これを処理する私のコードは次のようになります:(パーサーはArgumentParser()インスタンスです)

subparsers = parser.add_subparsers(title="Commands")

foo = subparsers.add_parser("foo", help="- foo does foo")
bar = subparsers.add_parser("bar", help="- bar does bar")

コマンドアクショングループの属性とメソッドを調べましたが、これを解決するものが見つからないようです(少なくとも私が理解できることから)。他の誰かがこれに対処したかどうかはわかりませんが、おそらく少しあいまいだと思います。繰り返しになりますが、私がやろうとしているのは、中括弧で囲まれたコマンドの冗長なリストを削除する方法を見つけることだけです。

4

3 に答える 3

15

「{foo、bar}」の部分は引数「metavar」です。metavarは、argparseがusage文字列とhelp文字列で予想される引数値を参照する方法です。argparseはサブコマンドを複数の選択肢がある引数のように扱うため、メタ変数を指定しない場合、デフォルトは中括弧で囲まれた選択肢(サブコマンド)のリストです。サブコマンドの可能なオプションをユーザーに知らせますが、それらはすぐ下にリストされているため、冗長であり、サブコマンドがたくさんある場合は醜いです。

自分で選択したメタバーに簡単に置き換えることができます。

subparsers = parser.add_subparsers(title="Commands", metavar="<command>")
于 2012-08-04T15:11:46.500 に答える
4

argparseのソースコードを深く掘り下げた後、冗長な選択リストを削除するためのハックを作成しました。{cmd1,...}

HelpFormatterこのハックは、サブパーサーアクションを処理するときにのフォーマットメソッドを変更するカスタムヘルプフォーマッターを実装します。具体的には、サブコマンド引数グループのサブパーサーmetavarと 行を削除し、それらのサブコマンドの余分なインデントを削除します。help

注意して使用してください

python3.6でテストされたpython3バージョン

from argparse import ArgumentParser, HelpFormatter, _SubParsersAction

class NoSubparsersMetavarFormatter(HelpFormatter):

    def _format_action(self, action):
        result = super()._format_action(action)
        if isinstance(action, _SubParsersAction):
            # fix indentation on first line
            return "%*s%s" % (self._current_indent, "", result.lstrip())
        return result

    def _format_action_invocation(self, action):
        if isinstance(action, _SubParsersAction):
            # remove metavar and help line
            return ""
        return super()._format_action_invocation(action)

    def _iter_indented_subactions(self, action):
        if isinstance(action, _SubParsersAction):
            try:
                get_subactions = action._get_subactions
            except AttributeError:
                pass
            else:
                # remove indentation
                yield from get_subactions()
        else:
            yield from super()._iter_indented_subactions(action)

parser = ArgumentParser(formatter_class=NoSubparsersMetavarFormatter)
subparsers = parser.add_subparsers(title="Commands")

foo = subparsers.add_parser("foo", help="- foo does foo")
bar = subparsers.add_parser("bar", help="- bar does bar")

parser.parse_args(['-h'])

python2.7でテストされたpython2バージョン

from argparse import ArgumentParser, HelpFormatter, _SubParsersAction

class NoSubparsersMetavarFormatter(HelpFormatter):

    def _format_action(self, action):
        result = super(NoSubparsersMetavarFormatter,
                       self)._format_action(action)
        if isinstance(action, _SubParsersAction):
            return "%*s%s" % (self._current_indent, "", result.lstrip())
        return result

    def _format_action_invocation(self, action):
        if isinstance(action, _SubParsersAction):
            return ""
        return super(NoSubparsersMetavarFormatter,
                     self)._format_action_invocation(action)

    def _iter_indented_subactions(self, action):
        if isinstance(action, _SubParsersAction):
            try:
                get_subactions = action._get_subactions
            except AttributeError:
                pass
            else:
                for subaction in get_subactions():
                    yield subaction
        else:
            for subaction in super(NoSubparsersMetavarFormatter,
                                   self)._iter_indented_subactions(action):
                yield subaction

parser = ArgumentParser(formatter_class=NoSubparsersMetavarFormatter)
subparsers = parser.add_subparsers(title="Commands")

foo = subparsers.add_parser("foo", help="- foo does foo")
bar = subparsers.add_parser("bar", help="- bar does bar")

parser.parse_args(['-h'])

サンプル出力:

usage: a.py [-h] {foo,bar} ...

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

Commands:
  foo         - foo does foo
  bar         - bar does bar
于 2018-01-01T16:15:02.210 に答える
3

ヘルプメッセージのフォーマットをカスタマイズするには、独自のフォーマッタークラスを作成し、のインターフェイスに基づいて、引数argparse.HelpFormatterを使用してパーサーのコンストラクターに渡します。formatter_class

詳細については、http://docs.python.org/dev/library/argparse.html#formatter-classを参照してください。

于 2012-06-18T19:43:02.387 に答える