我想使用argparse来解析布尔命令行参数写为“——foo True”或“——foo False”。例如:
my_program --my_boolean_flag False
然而,下面的测试代码并没有做我想要的:
import argparse
parser = argparse.ArgumentParser(description="My parser")
parser.add_argument("--my_bool", type=bool)
cmd_line = ["--my_bool", "False"]
parsed_args = parser.parse(cmd_line)
可悲的是,parsed_args。my_bool的值为True。即使我将cmd_line更改为["——my_bool", ""],这也是如此,这是令人惊讶的,因为bool("")的值为False。
我怎么能得到argparse解析“假”,“F”,和他们的小写变体为假?
使用前面建议的另一个解决方案,但argparse的解析错误是“正确的”:
def str2bool(v):
if isinstance(v, bool):
return v
if v.lower() in ('yes', 'true', 't', 'y', '1'):
return True
elif v.lower() in ('no', 'false', 'f', 'n', '0'):
return False
else:
raise argparse.ArgumentTypeError('Boolean value expected.')
这对于使用默认值进行开关非常有用;例如
parser.add_argument("--nice", type=str2bool, nargs='?',
const=True, default=False,
help="Activate nice mode.")
允许我使用:
script --nice
script --nice <bool>
并且仍然使用默认值(特定于用户设置)。这种方法的一个(间接相关的)缺点是'nargs'可能会捕获一个位置参数——请参阅这个相关问题和这个argparse错误报告。
转换值:
def __arg_to_bool__(arg):
"""__arg_to_bool__
Convert string / int arg to bool
:param arg: argument to be converted
:type arg: str or int
:return: converted arg
:rtype: bool
"""
str_true_values = (
'1',
'ENABLED',
'ON',
'TRUE',
'YES',
)
str_false_values = (
'0',
'DISABLED',
'OFF',
'FALSE',
'NO',
)
if isinstance(arg, str):
arg = arg.upper()
if arg in str_true_values:
return True
elif arg in str_false_values:
return False
if isinstance(arg, int):
if arg == 1:
return True
elif arg == 0:
return False
if isinstance(arg, bool):
return arg
# if any other value not covered above, consider argument as False
# or you could just raise and error
return False
[...]
args = ap.parse_args()
my_arg = options.my_arg
my_arg = __arg_to_bool__(my_arg)
扩展杰拉德的回答
原因解析器。add_argument("——my_bool", type=bool)不起作用,因为bool("mystring")对于任何非空字符串都是True,所以bool("False")实际上是True。
你想要的是
my_program.py
import argparse
parser = argparse.ArgumentParser(description="My parser")
parser.add_argument(
"--my_bool",
choices=["False", "True"],
)
parsed_args = parser.parse_args()
my_bool = parsed_args.my_bool == "True"
print(my_bool)
$ python my_program.py --my_bool False
False
$ python my_program.py --my_bool True
True
$ python my_program.py --my_bool true
usage: my_program.py [-h] [--my_bool {False,True}]
my_program.py: error: argument --my_bool: invalid choice: 'true' (choose from 'False', 'True')