Argparse可选布尔

时间:2018-09-19 09:53:51

标签: python python-3.x argparse

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

  • 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)

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

python test.py --foo False

实际上最终存储了foo=True。发生了什么事?

2 个答案:

答案 0 :(得分:5)

您确定要使用该模式吗?对于布尔切换,--foo--foo <value>一起使用并不是常见的模式。

对于您的问题,请记住命令行值是 string ,并且type=bool表示您希望应用bool(entered-string-value)。对于--foo False表示bool("False"),产生True;所有非空字符串都是正确的!另请参见Why is argparse not parsing my boolean flag correctly?

我强烈建议 而不是支持--foo / --foo <string value>,建议您使用--foo来表示True,删除参数值,然后而是添加一个--no-foo选项以显式设置False

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

dest='foo'开关上的--no-foo附加项确保了它存储的False值(通过store_false)以相同的args.foo属性结尾。 / p>

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

如果您有特定的--no-foo倒置开关需求(因为仅省略 --foo就已经意味着“假” ),然后坚持使用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)
  • 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'

答案 1 :(得分:3)

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

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

因此没有--foo选项:

python test.py

将为False参数产生一个foo值,并出现--foo选项:

python test.py --foo

将为True参数产生一个foo值。