Pythonで 'argparse.ArgumentError'を使う

Pythonの argparse モジュールで ArgumentError 例外を使用したいのですが、どのように使用するのか分かりません。このシグネチャは、 ArgumentError(argument、message)として呼び出されるべきだと言いますが、引数がどのようなものであるべきかわかりません。私はそれがパーサーオブジェクトの一部であるべきだと思うが、私はそれについてのドキュメントを見つけることができなかった。

35
既存のクラスと同じように、カスタム Action クラス内で使用できます。しかし、私は parser の外でそれを行う理由を想像することはできません。これは特別なことではなく、エラーメッセージに Action という名前を追加するだけです。コード内でのその使用方法を調べます。
追加された 著者 hpaulj,
追加された 著者 DavidRR,

2 答え

ソースドキュメントから:

ArgumentError:パーサーのアクションにエラーがある場合に、ArgumentParserオブジェクトによって生成された例外です。コマンドラインの解析中に発生したエラーは、ArgumentParserによって捕捉され、コマンドラインメッセージとして出力されます。

コンストラクタの argument パラメータは、例外が発生した Action オブジェクトです。通常、 Action サブクラスの外にそれを呼び出す必要はなく、サブクラス化するときに明示的に呼び出す必要はありません。通常は ValueError (またはそれ以外のもの)を作成します。

0と1の間の浮動小数点値

あなたのコメントに関しては、0と1の間の浮動小数点値だけを受け入れたいと思っています。このために、カスタム型を定義する能力を使うべきです。例えば、次のようにすることができます:

def percentFloat (string):
    value = float(string)
    if value < 0 or value > 1:
        raise argparse.ArgumentTypeError('Value has to be between 0 and 1')
    return value

parser = argparse.ArgumentParser()
parser.add_argument('test', type=percentFloat)
parser.parse_args()

float(string)は、 argparseによって無効な型エラーを引き起こす非浮動小数点数に対して ValueError を発生させるので、非浮動小数点に対しても安全ですモジュールです。 ArgumentTypeError は単なる指定方法ですカスタムエラーメッセージ。

相互に排他的なパラメータ

For 相互に排他的なパラメータ, you should use argparse.add_mutually_exclusive_group.

パラメータの依存性

パラメータの依存性 isn’t really something that should be done by the argument parser. For semantic details, you should instead simply do it yourself:

args = parser.parse_args()
if args.w and not args.p:
    parser.error('-p is required when -w is set.')

ArgumentParser.error を使用してカスタムを呼び出すことができますエラーメッセージが表示され、プログラムが中断され、コンソールに出力されます。

しかしもちろん、このような基本的な状況では、できるだけ暗黙のうちに -p を推測するほうがはるかに意味があります。

49
追加された
それは正しいことではありません。値を送信するだけで、 AttributeError: 'float'オブジェクトに 'option_strings' という属性はありません。
追加された 著者 asmeurer,
ところで、モジュールを直接サポートしない型チェックをしたいので、私はそれを使いたいと思っています。たとえば、0から1までの浮動小数点値が必要です。argparseは浮動小数点型にする必要があることを指定しますが、手動で範囲を確認する必要があります。これは、値が間違っているときに出力する正しいエラーのようです。
追加された 著者 asmeurer,
ダウンボートは答えが間違っているからです。 ArgumentError(1.1、 "値が範囲外")は、上記のようにAttributeErrorを発生させます。これは何らかの内部argparseオブジェクトである必要がありますが、私は何が分かりません。ところで、これをやりたいときのもう一つの例は、argparseモジュールが直接的にサポートしていない引数に対して、自明ではない依存関係を定義したいときです。 -w オプションのようなものは、 -p オプションを必要とするか、 -n-N
追加された 著者 asmeurer,
ありがとう。そのparser.errorは私が探していたものでした。
追加された 著者 asmeurer,
@asmeurer私の答えを編集して、それを行う方法の例を教えてください。
追加された 著者 poke,
私の答えを更新しました。
追加された 著者 poke,

parser.error()は、おそらくほとんどの人が望むものですが、argparse.ArgumentError()を使うこともできます(質問にあるように)。 > bar_arg をクリックします。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--foo')
bar_arg = parser.add_argument('--bar')

args = parser.parse_args()
if args.bar == 'xyzzy':
    raise argparse.ArgumentError(bar_arg, "Can't be 'xyzzy'")

if args.foo == 'xyzzy':
    parser.error("Can't be 'xyzzy'")

これにより、次のような出力が得られます。

$ python argparse_test.py --foo xyzzy
usage: argparse_test.py [-h] [--foo FOO] [--bar BAR]
argparse_test.py: error: Can't be 'xyzzy'

$ python argparse_test.py --bar xyzzy
Traceback (most recent call last):
  File "argparse_test.py", line 10, in 
    raise argparse.ArgumentError(bar_arg, "Can't be 'xyzzy'")
argparse.ArgumentError: argument --bar: Can't be 'xyzzy'
11
追加された
これは、 parser の外部で ArgumentError を使用することは可能ですが、 parser.error を使用した場合よりも劣る可能性があります。
追加された 著者 hpaulj,
さて、あなたがエラーメッセージをうまく書いていれば、どのスイッチが問題のものであるかを言及することが確実です。追加された引数ごとに別々の変数を作成することは非常に面倒です...
追加された 著者 Praveen,
@hpaulj、はい、ArgumentErrorには1つの利点があります。これは、どのスイッチが問題のスイッチであったかを知ることができます。
追加された 著者 ukrutt,
@プラベーンそれは私が推測する優先事項の問題です。私自身、スイッチの適切な名前が何であったかを覚えておく必要があるので、 "--foo"は "xyzzy"にすることはできません( argsの属性と必ずしも同じではありません)。しかし正直なところ、 parser.error()にはデフォルトで違反しているスイッチの名前を含めるべきだと思います。
追加された 著者 ukrutt,