使用argparse解析布尔值

1098 投票
28 回答
897660 浏览
提问于 2025-04-17 16:39

我想用 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 呢?

28 个回答

506

这是另一个使用之前建议的解决方案,但这次能正确处理来自 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 的错误报告

1484

我觉得更标准的做法是通过以下方式来实现:

command --feature

还有

command --no-feature

argparse 在这个版本中支持得很好:

Python 3.9 及以上版本

parser.add_argument('--feature', action=argparse.BooleanOptionalAction)

对于 Python 3.9 以下的版本:

parser.add_argument('--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?
40

最简单也是最正确的方法是:

from distutils.util import strtobool

parser.add_argument('--feature', dest='feature', 
                    type=lambda x: bool(strtobool(x)))

请注意,代表“真”的值有 y、yes、t、true、on 和 1;而代表“假”的值有 n、no、f、false、off 和 0。如果输入的值不在这些范围内,就会出现一个叫做 ValueError 的错误。

撰写回答