24

私は Python (2.7) の argparse 機能を使用しており、生成されるヘルプをオプションでアルファベット順に自動的に並べ替えたいと考えています。

デフォルトでは、次のように、ヘルプ エントリは追加された順に並べ替えられます*。

p = argparse.ArgumentParser(description='Load duration curves and other plots')
p.add_argument('--first', '-f', type=int, default=1, help='First Hour')
p.add_argument('--dur', '-d', type=int, default=-1, help='Duration in Hours. Use -1 for all')
p.add_argument('--title', '-t', help='Plot Title (for all plots), default=file name')
p.add_argument('--interp', '-i', action="store_true", default=True, 
                help='Use linear interpolation for smoother curves')
...
args = p.parse_args()

as を呼び出すと、次のものpython script -hが生成されます。

usage: script.py [-h] [--first FIRST] [--dur DUR] [--title TITLE] [--interp]

Load duration curves and other plots

optional arguments:
  -h, --help            show this help message and exit
  --first FIRST, -f FIRST
                        First Hour
  --dur DUR, -d DUR     Duration in Hours. Use -1 for all
  --title TITLE, -t TITLE
                        Plot Title (for all plots), default=file name
  --interp, -i          Use linear interpolation for smoother curves

代わりにアルファベット順に自動的にソートすることは可能ですか? dur、first、h、interp、title のようになります。

*明らかに、回避策は p.add_argument を使用してアルファベット順にエントリを追加することで手動で維持することですが、私はそうしないようにしています。

4

5 に答える 5

26

カスタムHelpFormatterクラスを提供することでこれを行うことができます。その内部は公式には文書化されていません。これは、Python のバージョンからバージョンへの互換性に関しては自分で判断する必要があることを意味しますが、インターフェイスは非常に安定していると思います。

from argparse import HelpFormatter
from operator import attrgetter

class SortingHelpFormatter(HelpFormatter):
    def add_arguments(self, actions):
        actions = sorted(actions, key=attrgetter('option_strings'))
        super(SortingHelpFormatter, self).add_arguments(actions)


p = argparse.ArgumentParser(...
    formatter_class=SortingHelpFormatter,
)

ここでは、オプション文字列 (('--dur', '-d')など) で並べ替えていますが、並べ替えの対象を選択することもできます。この単純な並べ替えオプションは、オプションのように、一重ダッシュのオプションを最後に配置し-hます。

出力:

usage: [-h] [--first FIRST] [--dur DUR] [--title TITLE] [--interp]

Load duration curves and other plots

optional arguments:
  --dur DUR, -d DUR     Duration in Hours. Use -1 for all
  --first FIRST, -f FIRST
                        First Hour
  --interp, -i          Use linear interpolation for smoother curves
  --title TITLE, -t TITLE
                        Plot Title (for all plots), default=file name
  -h, --help            show this help message and exit
于 2012-09-04T18:13:19.967 に答える
1

これは@mgilsonの答えに似ています。以前投稿したと思っていたのですが、そうではないようです。

d = dict()
d['--first'] = ('-f', "type=int", "default=1", "help='First Hour'")
d['--dur'] = ('-d', type=int, default=-1, help='Duration in Hours. Use -1 for all')
# etc

for prim_option in sorted(d):
    p.add_arguments(prim_option, *d[prim_option])

ディクショナリでキーとして正確に使用されるものと、 への引数sortedおよび への呼び出しの正確な構造を調整しadd_argumentsて、目的の並べ替え順序を取得できます。これは、公式に文書化された のインターフェースに準拠していますがargparse、パーサーを定義するプロセスにレイヤーを追加します。(あなたの哲学にもよりますが、パーサーの実装からオプションに関する情報を分離することは良いことかもしれません。)

于 2012-09-05T13:33:23.870 に答える
1

ArgumentParser クラスを作成するときに、ヘルプ フォーマッタを渡すことができます: http://docs.python.org/library/argparse.html#formatter-class

したがって、明らかに提供されているフォーマッタの 1 つを使用できますが、少しリバース エンジニアリングせずにオーバーライドして置き換えることはできません。

>>> h = argparse.ArgumentDefaultsHelpFormatter
>>> print h.__doc__
Help message formatter which adds default values to argument help.

    Only the name of this class is considered a public API. All the methods
    provided by the class are considered an implementation detail.
于 2012-09-04T17:59:11.623 に答える
1

@MartijnPietersによって提案された方法よりも、間違いなく醜い方法です。

p = argparse.ArgumentParser()

#add arguements here

for g in p._action_groups:
    g._group_actions.sort(key=lambda x:x.dest)

これをtry/except句に入れると便利な場合があります。これは書式設定の助けにすぎないため、このコードの一部が何かで失敗しても、プログラムの実行には問題になりませんAttributeError...

于 2012-09-04T18:29:01.387 に答える
1

ヘルプ内の引数の順序は、parser.format_helpメソッドによって決まります。

Definition:  parser.format_help(self)
Source:
    def format_help(self):
        formatter = self._get_formatter()
        ...
        # positionals, optionals and user-defined groups
        for action_group in self._action_groups:
            formatter.start_section(action_group.title)
            formatter.add_text(action_group.description)
            formatter.add_arguments(action_group._group_actions)
            formatter.end_section()

helpオブジェクトをフェッチし、formatterそれに「セクション」を追加することによって作成されます。ここでは、 をループして_action_groups、それぞれを独自のセクションに配置し、そのアクション (引数) をadd_argumentsメソッドに追加します。フォーマッタは一時的なもので、文字列 (通常は複数行) を作成するためだけに存在します。

アクション グループには、既定のpostionalsoptionalsに加えて、ユーザーが作成するすべての が含まれます。これらのグループは、解析ではなくヘルプにのみ使用されます。したがって、action_group._group_actions解析に影響を与えずにリストを並べ替えることができます。(パーサーには独自のアクション リストがありparser._actionsます)。

p._actionsこれは、並べ替えはヘルプに影響しないが、並べ替えは影響するという@mgilsonの観察を裏付けて_group_actionsいます。

並べ替えは、 (ヘルプの一部であるかスタンドアロンであるかにかかわらず) 以下_actionsに影響します。usage

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

action_groups使用セクションに渡されないことに注意してください。使用法セクションでは、アクションの順序が変更され、optionals最初に表示され、次にが表示されpositionalsます。

add_argumentポジショナルの解析順序とその使用順序を制御する場合は、ステージの前/ステージ中に引数を並べ替えます。

ヘルプ グループの順序を制御したいだけの場合は._group_actions、フォーマッタを呼び出す前、またはリスト内で自由に並べ替えてください。

usage. _ positionalsたとえば、後に注文したくない人もいoptionalsます。

Formatter クラスが扱いにくいことに同意します。しかし、ほとんどの場合、Parser クラスとは別のものです。したがって、解析への影響を最小限に抑えて書き直すことができます。既存の Formatter サブクラスは、行の折り返しを制御し、行の書式設定を支援する低レベルのメソッドを微調整するだけです。パーサーとフォーマッターの間の重要なインターフェイスはformat_usageandformat_helpメソッドで、比較的単純で高レベルです。

サブクラス化

@grieve が引用符を付けているという警告にもかかわらず、人々はHelpFormatter自分のニーズに合わせて をサブクラス化します。人々がそうするのを妨げている唯一のものは、ある種の会社の方針です。すべての警告は、argparse の開発者が、ユーザーが行う可能性のあるすべての変更を想像したり文書化したりしようとしていないことを示しています。過去数年間に提案したものを列挙することさえできませんでした.

于 2015-09-27T22:59:06.700 に答える