Argparse可选布尔

Hyp*_*ane 6 python argparse python-3.x

我正在尝试获得以下行为:

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

当我使用时有效

    parser.add_argument('--foo',nargs='?', default=False, const=True)
Run Code Online (Sandbox Code Playgroud)

但是,如果我添加type=bool,则尝试将强制转换为布尔值会中断。在这种情况下

python test.py --foo False
Run Code Online (Sandbox Code Playgroud)

实际最终存储foo=True。这是怎么回事??

blh*_*ing 16

您应该使用action='store_true'参数代替布尔参数:

parser.add_argument('--foo', action='store_true')
Run Code Online (Sandbox Code Playgroud)

所以没有--foo选项:

python test.py
Run Code Online (Sandbox Code Playgroud)

将导致参数的Falsefoo,以及--foo选项的存在:

python test.py --foo
Run Code Online (Sandbox Code Playgroud)

将导致参数的Truefoo

  • 但这不允许`--foo bool`。 (2认同)
  • 当然,但是有*有*用例用于指定*禁用 foo 选项*,特别是在“来自多个来源的合并配置(包括命令行)”场景中。`--no-foo` 是通常的选择。 (2认同)

Mar*_*ers 11

确定需要这种模式吗?--foo--foo <value>,对于布尔开关而言,不是常用的模式。

对于您的问题,请记住,命令行值是一个字符串,并且type=bool意味着您要bool(entered-string-value)应用。对于--foo False该装置bool("False"),产生True; 所有非空字符串都是正确的!请参阅为什么argparse无法正确解析我的布尔标志?也一样

强烈建议您使用Mean ,而不是支持--foo/ --foo <string value>,删除参数值,然后添加一个选项来显式设置:--fooTrue--no-fooFalse

parser.add_argument('--foo', default=False, action='store_true')
parser.add_argument('--no-foo', dest='foo', action='store_false')
Run Code Online (Sandbox Code Playgroud)

dest='foo'对加法--no-foo开关保证了False它存储值(通过store_false)在相同的最终args.foo属性。

--foo / --no-foo当您将其他配置机制设置foo为,True并且需要使用命令行开关再次覆盖时,才需要组合。--no-<option>是广泛使用的用于反转布尔型命令行开关的标准。

如果您对倒置开关没有特别的要求--no-foo(因为仅省略 --foo它就意味着'false'),那么请坚持使用该action='store_true'选项。这使您的命令行简单明了!

但是,如果您的用例或其他约束明确要求您的命令行必须有一定的--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)
Run Code Online (Sandbox Code Playgroud)
  • 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'
Run Code Online (Sandbox Code Playgroud)