你确定你需要那个模式吗? --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')
--no-foo 开关上的dest='foo' 添加确保它存储的False 值(通过store_false)最终使用相同的args.foo 属性。
从 Python 3.9 开始,您还可以使用 argparse.BooleanOptionalAction 操作类:
parser.add_argument("--foo", action=argparse.BooleanOptionalAction)
它会有同样的效果,处理--foo和--no-foo来设置和清除标志。
如果您有一些其他配置机制可以将foo 设置为True,并且您需要使用命令行开关再次覆盖它,您只需要--foo / --no-foo 组合。 --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 时,此处设置foo=True。
-
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'