2012-09-04 17 views
16

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

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 

それが自動的にアルファベット順にソートすることが可能です:python script -hとして呼び出されたときに生成

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() 

:デフォルトのヘルプ項目によって

はのように、彼らは*追加された順にソートされています代わりに?これは、まず、h、interp、titleとなるでしょう。

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

+0

私はあなたがp.show_helpか何かをフックして、手作業でargリストを解析できると思います...私はそれについてドキュメントを見つけることができるかどうかを見ていきます... –

答えて

16

これを行うには、カスタムHelpFormatter classを入力します。その内部は正式に文書化されていない。あなたは可能性があり

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')、)オプション文字列に、しかし:これは、Pythonのバージョンからのバージョンとの互換性に来るときあなたがあなた自身であるが、私はインターフェイスは非常に安定して見つけること並べ替えたいものを選択してください。このシンプルなソートオプションは、最後にダッシュオプション(-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 
+0

'' Super(HelpFormatter'''は '' Super(SortingHelpFormatter'' – jterrace

+0

nevermind、あなたはそれを持っています:) – jterrace

+1

* whistles innocently * –

1

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

だから、明らかにあなたが供給フォーマッタのいずれかを使用することができますが、逆のビットを操作することなく、それらを上書きして置き換えることはできません。

>>> 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. 
+0

私はしばしば、ユーザーは - /(いくつかのフォーマッタを用意しておけば、ユーザーが何らかの方法でそれらを混乱させることは許されない) - コードがかなり醜く、書くのが難しく、argparse開発者がユーザーにそれを服従させる。 – mgilson

+1

'argparse'は、' optparse'コードベースを拡張することの醜さと難しさに動機づけられたので、これは皮肉です。 – chepner

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か何かで失敗した場合、プログラムの実行に関して本当に重要ではありません。

+1

それは私も考えて、うまくいくように思えました。しかし、私は 'p._group_actions'の順序を変えることでどのような副作用が起こるのかを簡単には知ることができないので、それを示唆するのは快適ではありませんでした。 'p._actions'のアクショングループはどうですか?それらの秩序は、何らかの形でこのものに結びついて、変わる必要があるでしょうか?だから答えはupvoteではなく、コードとハック値を掘り起こすための精神+1 ;-) –

+0

@LukasGraf - 私はこのソリューションは物事を混乱させないと保証しませんが、私は考える*それはかなり安全です。とにかく順不同の辞書を使用してすべてが解析されているようです(ヘルプメッセージを書式設定する目的でのみ注文されているようです)。私は 'p._actions'をソートしようとしましたが、それは何の効果もないようです... – mgilson

+0

変更したいのはヘルプ行の順番で、' _group_actions'リストをソートするのは論理的です。 – hpaulj

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への呼び出しの正確な構造として使用されているものを調整することができます。これは公開されている​​のインターフェイスに準拠していますが、パーサーを定義するプロセスにレイヤーが追加されています。 (あなたの哲学に応じて、パーサーの実装からオプションに関する情報を分離することは良いことかもしれません。)

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() 

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

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

これは、@ mgilsonの観察によれば、p._actionsのソートはヘルプには影響しませんが、_group_actionsをソートすることが分かります。

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

action_groupsは、使用方法のセクションに渡されていないことに注意してください:_actionsをソート

usage(ヘルプまたはスタンドアロンの一部かどうか)に影響を及ぼします。使用セクションでは、最初にoptionalsと表示され、次にpositionalsと表示されます。

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

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

usageのアクションの順序を制御することに関するその他のご質問があります。たとえば、optionalsの後にpositionalsを注文したくない人もいます。

私は、Formatterクラスが煩雑であることに同意します。しかし、ほとんどの場合、Parserクラスとは別です。したがって、構文解析に与える影響を最小限に抑えて書き直すことができました。既存のFormatterサブクラスは、ローレベルのメソッドを調整するだけで、行の折り返しを制御し、行の整形を助けます。パーサとフォーマッタの間の重要なインタフェースは、比較的簡単で高レベルのformat_usageformat_helpメソッドです。

関連する問題