Argparse:「オプションの引数」の下にリストされている必須の引数?


229

次の簡単なコードを使用して、いくつかの引数を解析します。そのうちの1つが必要であることに注意してください。残念ながら、ユーザーが引数を指定せずにスクリプトを実行すると、表示される使用法/ヘルプテキストは、オプションではない引数があることを示していません。引数がオプションではないことを示すようにpythonを取得するにはどうすればよいですか?

これがコードです:

import argparse
if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Foo')
    parser.add_argument('-i','--input', help='Input file name', required=True)
    parser.add_argument('-o','--output', help='Output file name', default="stdout")
    args = parser.parse_args()
    print ("Input file: %s" % args.input )
    print ("Output file: %s" % args.output )

必要な引数を提供せずに上記のコードを実行すると、次の出力が得られます。

usage: foo.py [-h] -i INPUT [-o OUTPUT]

Foo

optional arguments:
    -h, --help            show this help message and exit
    -i INPUT, --input INPUT
                          Input file name
    -o OUTPUT, --output OUTPUT
                          Output file name

5
使用法の行では、-i INPUTパーツは角括弧で囲まれていません。これは、実際に必要であることを微妙に示しています。また、手動でそのを通じて説明することができhelpPARAM
ハイメRGP

7
@JaimeRGPはい、もちろんそれだけでは不十分で、目立つほどではありません。optional arguments必要な引数に割り当てられたグループ名は、依然として誤解を招く可能性があります。
Acumenus 2016年

回答:


316

-またはで始まるパラメーター--は、通常はオプションと見なされます。他のすべてのパラメーターは位置パラメーターであり、(位置関数の引数のように)設計上必要です。オプションの引数を要求することは可能ですが、これは設計に少し反します。それらは依然として非定位置引数の一部であるため、たとえそれらが必要な場合でも、混乱するヘッダー「オプション引数」の下に引き続きリストされます。ただし、使用法の部分に角括弧がないことは、それらが実際に必要であることを示しています。

ドキュメントも参照してください:

一般に、argparseモジュールは、-fや--barなどのフラグがオプションの引数を示していると想定しています。これは、コマンドラインでは常に省略できます。

注:ユーザーがオプションをオプションであることを期待しているため、必要なオプションは一般に不適切なフォームと見なされ、可能な場合は回避する必要があります。

つまり、ヘルプの「位置引数」「オプション引数」のヘッダーは、引数が自動的に分離される2つの引数グループによって生成されます。これで、「ハックイン」してオプションの名前を変更できますが、はるかに洗練された解決策は、「必須の名前付き引数」(またはそれらを呼び出すもの)の別のグループを作成することです。

parser = argparse.ArgumentParser(description='Foo')
parser.add_argument('-o', '--output', help='Output file name', default='stdout')
requiredNamed = parser.add_argument_group('required named arguments')
requiredNamed.add_argument('-i', '--input', help='Input file name', required=True)
parser.parse_args(['-h'])
usage: [-h] [-o OUTPUT] -i INPUT

Foo

optional arguments:
  -h, --help            show this help message and exit
  -o OUTPUT, --output OUTPUT
                        Output file name

required named arguments:
  -i INPUT, --input INPUT
                        Input file name

同じ問題が発生しています。解決策を試してみました。新しいグループに引数を追加しますが、私のコードはその後機能しないようです。どんな解決策もいただければ幸いです。私のコードへのリンク-pastebin.com/PvC2aujz
Zarar Mahmud

1
@ZararMahmud:コードの24行目で空の引数を渡しています。parser.parse_args([])代わりに、parser.parse_args()引数なしでsys.argvの内容をキャプチャしてください。argparse
Devin

@poke:素敵な解決策!しかし、これは、相互に排他的なグループが必要な場合、または私が何か不足している場合には役に立ちませんか?
裁判官


79

私はオプションの前に必要な引数をリストすることを好むので、私はそれをハックします:

    parser = argparse.ArgumentParser()
    parser._action_groups.pop()
    required = parser.add_argument_group('required arguments')
    optional = parser.add_argument_group('optional arguments')
    required.add_argument('--required_arg', required=True)
    optional.add_argument('--optional_arg')
    return parser.parse_args()

そしてこの出力:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
               [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

optional arguments:
  --optional_arg OPTIONAL_ARG

オプションの引数グループに「ヘルプ」が表示されなくても私は生きることができます。


3
これは実際にargparseに必要に応じて引数のいずれかを処理させるのですか?
Anthony

6
引数を追加するときに、「必須」引数を設定する必要があると思います。
Karl Rosaen、2017年

それは本当にうれしいです。
ポールセザンヌ

7
@Anthony-そのために、add_argumentに「required = True」は必要ありません。上記の答えは、引数のグループ化を示しています。
user2275693 2018

47

@Karl Rosaenの建物

parser = argparse.ArgumentParser()
optional = parser._action_groups.pop() # Edited this line
required = parser.add_argument_group('required arguments')
# remove this line: optional = parser...
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')
parser._action_groups.append(optional) # added this line
return parser.parse_args()

そしてこの出力:

usage: main.py [-h] [--required_arg REQUIRED_ARG]
           [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

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

1
ところで、_action_group保護されたメンバーにアクセスせずにアクセスする方法(メソッド)はありますか?私の場合、既存の(カスタム)グループに引数を追加する必要があります。
machin 2017

これは素晴らしい。2番目のオプションリストに表示される--help項目を解決します。
ジェレミー

:この回答は公開されたAPIに違反します。下のBryan_Dによる回答を確認してください。

18

もう一度、@ RalphyZから構築します

これは公開されたAPIを壊しません。

from argparse import ArgumentParser, SUPPRESS
# Disable default help
parser = ArgumentParser(add_help=False)
required = parser.add_argument_group('required arguments')
optional = parser.add_argument_group('optional arguments')

# Add back help 
optional.add_argument(
    '-h',
    '--help',
    action='help',
    default=SUPPRESS,
    help='show this help message and exit'
)
required.add_argument('--required_arg', required=True)
optional.add_argument('--optional_arg')

上記と同じように表示され、将来のバージョンでも存続するはずです。

usage: main.py [-h] [--required_arg REQUIRED_ARG]
           [--optional_arg OPTIONAL_ARG]

required arguments:
  --required_arg REQUIRED_ARG

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

RalphyZの答えが公開されたAPIをどのように壊すか説明できますか?
jeremysprofile

5
_action_groups内部使用のみを目的としています。したがって、バージョン間の互換性は保証されません。
Bryan_D
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.