我正在尝试获得以下行为:
当我使用时可以使用
parser.add_argument('--foo',nargs='?', default=False, const=True)
但是,如果我添加type=bool
并试图强制将其强制转换为布尔值,则会中断。在这种情况下
python test.py --foo False
实际上最终存储了foo=True
。发生了什么事?
答案 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
值。