入力オプションの解析に argparse
in Python 2.7 を使用しています。私のオプションの1つは複数選択です。ヘルプテキストでリストを作成したい。
from argparse import ArgumentParser
parser = ArgumentParser(description='test')
parser.add_argument('-g', choices=['a', 'b', 'g', 'd', 'e'], default='a',
help="Some option, where\n"
" a = alpha\n"
" b = beta\n"
" g = gamma\n"
" d = delta\n"
" e = epsilon")
parser.parse_args()
ただし、argparse
は、すべての改行と連続するスペースを削除します。結果は次のようになります
〜/ Downloads:52 $ python2.7 x.py -h usage:x.py [-h] [-g {a、b、g、d、e}] test オプションの引数: -h、--helpこのヘルプメッセージを表示して終了 -g {a、b 、g、d、e} a =アルファb =ベータg =ガンマd =デルタe = epsilon
ヘルプテキストに改行を挿入する方法は?
RawTextHelpFormatter
を使用してみてください:
from argparse import RawTextHelpFormatter
parser = ArgumentParser(description='test', formatter_class=RawTextHelpFormatter)
1つのオプションをオーバーライドする場合は、RawTextHelpFormatter
を使用しないでください。代わりにHelpFormatter
をサブクラス化し、「生」で処理する必要があるオプションの特別なイントロを提供します("R|rest of help"
を使用します):
import argparse
class SmartFormatter(argparse.HelpFormatter):
def _split_lines(self, text, width):
if text.startswith('R|'):
return text[2:].splitlines()
# this is the RawTextHelpFormatter._split_lines
return argparse.HelpFormatter._split_lines(self, text, width)
そしてそれを使用します:
from argparse import ArgumentParser
parser = ArgumentParser(description='test', formatter_class=SmartFormatter)
parser.add_argument('-g', choices=['a', 'b', 'g', 'd', 'e'], default='a',
help="R|Some option, where\n"
" a = alpha\n"
" b = beta\n"
" g = gamma\n"
" d = delta\n"
" e = epsilon")
parser.parse_args()
ヘルプがR|
で始まらない.add_argument()
への他の呼び出しは、通常どおりラップされます。
これは argparseの改善点 の一部です。完全なSmartFormatterは、すべてのオプションへのデフォルトの追加、およびユーティリティの説明の生の入力もサポートしています。フルバージョンには独自の_split_lines
メソッドがあります。バージョン文字列は保持されます:
parser.add_argument('--version', '-v', action="version",
version="version...\n 42!")
別の簡単な方法は、textwrapを含めることです。
例えば、
import argparse, textwrap
parser = argparse.ArgumentParser(description='some information',
usage='use "python %(prog)s --help" for more information',
formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('--argument', default=somedefault, type=sometype,
help= textwrap.dedent('''\
First line
Second line
More lines ... '''))
このようにして、各出力行の前にある長い空きスペースを避けることができます。
usage: use "python your_python_program.py --help" for more information
Prepare input file
optional arguments:
-h, --help show this help message and exit
--argument ARGUMENT
First line
Second line
More lines ...
同様の問題に直面しました(Python 2.7.6)。 RawTextHelpFormatter
を使用して、descriptionセクションをいくつかの行に分解しようとしました。
parser = ArgumentParser(description="""First paragraph
Second paragraph
Third paragraph""",
usage='%(prog)s [OPTIONS]',
formatter_class=RawTextHelpFormatter)
options = parser.parse_args()
そして得た:
使用法:play-with-argparse.py [オプション] 最初の段落 2番目の段落 3番目の段落 オプションの引数: -h、--helpこのヘルプメッセージを表示して終了
したがって、RawTextHelpFormatter
は解決策ではありません。ソースコードに表示されるとおりに説明を印刷し、すべての空白文字を保持するため(読みやすくするためにソースコードに余分なタブを保持したいが、すべてを印刷したくない。また、生のフォーマッタは行を折り返さない長すぎる、たとえば80文字以上)。
正しい方向を示唆した@Antonに感謝します 上記 。しかし、そのソリューションはdescriptionセクションをフォーマットするためにわずかな修正が必要です。
とにかく、カスタムフォーマッタが必要です。既存のHelpFormatter
クラスを拡張し、_fill_text
メソッドを次のようにオーバーライドしました。
import textwrap as _textwrap
class MultilineFormatter(argparse.HelpFormatter):
def _fill_text(self, text, width, indent):
text = self._whitespace_matcher.sub(' ', text).strip()
paragraphs = text.split('|n ')
multiline_text = ''
for paragraph in paragraphs:
formatted_paragraph = _textwrap.fill(paragraph, width, initial_indent=indent, subsequent_indent=indent) + '\n\n'
multiline_text = multiline_text + formatted_paragraph
return multiline_text
argparse モジュールからの元のソースコードと比較してください:
def _fill_text(self, text, width, indent):
text = self._whitespace_matcher.sub(' ', text).strip()
return _textwrap.fill(text, width, initial_indent=indent,
subsequent_indent=indent)
元のコードでは、説明全体がラップされています。上記のカスタムフォーマッタでは、テキスト全体がいくつかのチャンクに分割され、それぞれが個別にフォーマットされます。
そのため、カスタムフォーマッタを使用して:
parser = ArgumentParser(description= """First paragraph
|n
Second paragraph
|n
Third paragraph""",
usage='%(prog)s [OPTIONS]',
formatter_class=MultilineFormatter)
options = parser.parse_args()
出力は次のとおりです。
使用法:play-with-argparse.py [オプション] 最初の段落 2番目の段落 3番目の段落 オプションの引数: -h、--helpこのヘルプメッセージを表示して終了
説明テキストに手動で改行を入れ、それを自動で折り返したいと思っていました。しかし、ここでの提案はどれも役に立たなかったので、ここでの回答にあるSmartFormatterクラスを変更しました。 argparseメソッド名の問題はパブリックAPIにもかかわらず、私が持っているものです(test.py
と呼ばれるファイルとして):
import argparse
from argparse import RawDescriptionHelpFormatter
# call with: python test.py -h
class SmartDescriptionFormatter(argparse.RawDescriptionHelpFormatter):
#def _split_lines(self, text, width): # RawTextHelpFormatter, although function name might change depending on Python
def _fill_text(self, text, width, indent): # RawDescriptionHelpFormatter, although function name might change depending on Python
#print("splot",text)
if text.startswith('R|'):
paragraphs = text[2:].splitlines()
rebroken = [argparse._textwrap.wrap(tpar, width) for tpar in paragraphs]
#print(rebroken)
rebrokenstr = []
for tlinearr in rebroken:
if (len(tlinearr) == 0):
rebrokenstr.append("")
else:
for tlinepiece in tlinearr:
rebrokenstr.append(tlinepiece)
#print(rebrokenstr)
return '\n'.join(rebrokenstr) #(argparse._textwrap.wrap(text[2:], width))
# this is the RawTextHelpFormatter._split_lines
#return argparse.HelpFormatter._split_lines(self, text, width)
return argparse.RawDescriptionHelpFormatter._fill_text(self, text, width, indent)
parser = argparse.ArgumentParser(formatter_class=SmartDescriptionFormatter, description="""R|Blahbla bla blah blahh/blahbla (bla blah-blabla) a blahblah bl a blaha-blah .blah blah
Blah blah bla blahblah, bla blahblah blah blah bl blblah bl blahb; blah bl blah bl bl a blah, bla blahb bl:
blah blahblah blah bl blah blahblah""")
options = parser.parse_args()
2.7および3.4での動作は次のとおりです。
$ python test.py -h
usage: test.py [-h]
Blahbla bla blah blahh/blahbla (bla blah-blabla) a blahblah bl a blaha-blah
.blah blah
Blah blah bla blahblah, bla blahblah blah blah bl blblah bl blahb; blah bl
blah bl bl a blah, bla blahb bl:
blah blahblah blah bl blah blahblah
optional arguments:
-h, --help show this help message and exit
上記のSmartFomatterから始めて、私はそのソリューションを終了しました。
class SmartFormatter(argparse.HelpFormatter):
'''
Custom Help Formatter used to split help text when '\n' was
inserted in it.
'''
def _split_lines(self, text, width):
r = []
for t in text.splitlines(): r.extend(argparse.HelpFormatter._split_lines(self, t, width))
return r
奇妙なことに、トップレベルのパーサーに渡されるformatter_class引数はsub_parsersに継承されないため、作成されたsub_parserごとに再度渡す必要があることに注意してください。