web-dev-qa-db-ja.com

Argparseのオプションのブール値

私は次の動作を取得しようとしています:

  • python test.py => store foo = False
  • python test.py --foo => store foo = True
  • python test.py --foo bool => store foo = bool

私が使用すると動作します

    parser.add_argument('--foo',nargs='?', default=False, const=True)

ただし、type=boolを追加すると、ブール値へのキャストを強制しようとして失敗します。この場合

python test.py --foo False

実際にはfoo=Trueを保存することになります。どうしたの??

6
Hyperplane

sureそのパターンが必要ですか? --foo--foo <value>は、ブールスイッチの場合、一緒に使用する一般的なパターンではありません。

あなたの問題に関しては、コマンドラインの値はstringであり、type=boolbool(entered-string-value)を適用することを意味することを覚えておいてください。 --foo Falseの場合はbool("False")を意味し、Trueを生成します。空でない文字列はすべて真です! なぜargparseはブール値フラグを正しく解析しないのですか? も参照してください。

--foo/--foo <string value>をサポートする代わりに、strongly--fooを使用してTrueを意味することを推奨し、引数値をドロップし、代わりにFalseを明示的に設定する--no-fooオプション:

parser.add_argument('--foo', default=False, action='store_true')
parser.add_argument('--no-foo', dest='foo', action='store_false')

dest='foo'スイッチに--no-fooオプションを追加すると、_store_false属性で保存されるFalse値が(args.fooを介して)確実に終了します。

fooTrueに設定する他の構成メカニズムがあり、コマンドラインスイッチでこれを再度オーバーライドする必要がある場合にのみ、--foo / --no-fooの組み合わせが必要になります。 --no-<option>は、ブール型のコマンドラインスイッチを反転させるために広く採用されている標準です。

do n't--no-foo反転スイッチが特に必要な場合(単にomitting--fooはすでに 'false'を意味するため) action='store_true'オプションを使用するだけです。これにより、コマンドラインがシンプルかつ明確になります。

ただし、ユースケースまたはその他の制約により、コマンドラインmust--foo (true|false|0|1)サポートの王を必要とする場合は、独自のコンバーターを追加します。

def str_to_bool(value):
    if isinstance(value, bool):
        return value
    if value.lower() in {'false', 'f', '0', 'no', 'n'}:
        return False
    Elif value.lower() in {'true', 't', '1', 'yes', 'y'}:
        return True
    raise ValueError(f'{value} is not a valid boolean value')

parser.add_argument('--foo', type=str_to_bool, nargs='?', const=True, default=False)
  • const値は、nargs='?'引数に使用され、引数値は省略されます。ここでは、foo=Trueが使用されるときに--fooを設定します。
  • default=Falseは、スイッチがまったく使用されない場合に使用されます。
  • type=str_to_boolは、--foo <value>ケースの処理に使用されます。

デモ:

$ cat so52403065.py
from argparse import ArgumentParser

parser = ArgumentParser()

def str_to_bool(value):
    if value.lower() in {'false', 'f', '0', 'no', 'n'}:
        return False
    Elif value.lower() in {'true', 't', '1', 'yes', 'y'}:
        return True
    raise ValueError(f'{value} is not a valid boolean value')

parser.add_argument('--foo', type=str_to_bool, nargs='?', const=True, default=False)

print(parser.parse_args())
$ python so52403065.py
Namespace(foo=False)
$ python so52403065.py --foo
Namespace(foo=True)
$ python so52403065.py --foo True
Namespace(foo=True)
$ python so52403065.py --foo no
Namespace(foo=False)
$ python so52403065.py --foo arrbuggrhellno
usage: so52403065.py [-h] [--foo [FOO]]
so52403065.py: error: argument --foo: invalid str_to_bool value: 'arrbuggrhellno'
12
Martijn Pieters

ブール引数の代わりに action='store_true' パラメーターを使用する必要があります。

parser.add_argument('--foo', action='store_true')

--fooオプションがないため:

python test.py

False引数のfoo値、および--fooオプションの存在になります。

python test.py --foo

True引数のfoo値になります。

4
blhsing