1. ホーム
  2. パイソン

[解決済み】Argparse: 必須引数が「オプション引数」の下に表示される?

2022-03-30 19:59:27

質問

次のような簡単なコードで、いくつかの引数を解析していますが、そのうちの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

解決方法は?

で始まるパラメータ - または -- は通常オプションとみなされます。他のすべてのパラメータは位置パラメータであり、設計上必要です(位置関数の引数のように)。オプションの引数を要求することは可能ですが、これはその設計に少し反しています。それらはまだ非位置引数の一部であるため、必須であっても「オプション引数」という紛らわしいヘッダの下にリストアップされます。しかし、使用法の部分で角括弧がないのは、それらが本当に必要であることを示しています。

また ドキュメント :

一般に、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