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
,试图强制强制转换为Boolean,它就会中断。在这种情况下
python test.py --foo False
实际上存储了foo=True
。怎么回事??
解决方案
是否确实需要该模式?--foo
和--foo <value>
对于布尔开关而言,不是常用模式。
对于您的问题,请记住命令行值是字符串,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'
开关上的dest='foo'
加法可确保它存储的False
值(通过store_false
)在相同的args.foo
属性上结束。
从Python3.9开始,您还可以使用argparse.BooleanOptionalAction
操作类:
parser.add_argument("--foo", action=argparse.BooleanOptionalAction)
和它将具有相同的效果,处理--foo
和--no-foo
来设置和清除该标志。
foo
设置为True
的其他配置机制,并且需要使用命令行开关再次覆盖它,则只需要--foo / --no-foo
组合。--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)
const
值用于省略参数值的nargs='?'
参数。在这里,当使用--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'
相关文章