我想使用 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 来解析"False"
, "F"
及其小写变体为False
?
我认为更规范的方法是通过:
command --feature
和
command --no-feature
argparse
很好地支持此版本:
parser.add_argument('--feature', dest='feature', action='store_true')
parser.add_argument('--no-feature', dest='feature', action='store_false')
parser.set_defaults(feature=True)
当然,如果您真的想要--arg <True|False>
版本,则可以将ast.literal_eval
传递为 “类型”,或者传递用户定义的函数...
def t_or_f(arg):
ua = str(arg).upper()
if 'TRUE'.startswith(ua):
return True
elif 'FALSE'.startswith(ua):
return False
else:
pass #error condition maybe?
另一个解决方案使用先前的建议,但带有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>
并仍使用默认值(特定于用户设置)。这种方法的一个(间接相关的)缺点是 “水罐” 可能会引起位置争执 - 请参阅此相关问题和此 argparse 错误报告。
--feature
和--no-feature
(最后一个获胜)这使用户可以使用--feature
来创建 shell 别名,并使用--no-feature
覆盖它。
parser.add_argument('--feature', default=True, action=argparse.BooleanOptionalAction)
我建议 mgilson 的答案:
parser.add_argument('--feature', dest='feature', action='store_true')
parser.add_argument('--no-feature', dest='feature', action='store_false')
parser.set_defaults(feature=True)
--feature
和--no-feature
您可以使用互斥组:
feature_parser = parser.add_mutually_exclusive_group(required=False)
feature_parser.add_argument('--feature', dest='feature', action='store_true')
feature_parser.add_argument('--no-feature', dest='feature', action='store_false')
parser.set_defaults(feature=True)
如果要设置许多帮助器,则可以使用此帮助器:
def add_bool_arg(parser, name, default=False):
group = parser.add_mutually_exclusive_group(required=False)
group.add_argument('--' + name, dest=name, action='store_true')
group.add_argument('--no-' + name, dest=name, action='store_false')
parser.set_defaults(**{name:default})
add_bool_arg(parser, 'useful-feature')
add_bool_arg(parser, 'even-more-useful-feature')