我想使用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”,和他们的小写变体为假?


当前回答

我也在找同样的问题,恕我直言,漂亮的解决方案是:

def str2bool(v):
  return v.lower() in ("yes", "true", "t", "1")

并使用它将字符串解析为布尔值,如上所述。

其他回答

如果你想同时允许——特征和——无特征(最后一个胜出)

这允许用户使用——feature创建shell别名,并使用——no-feature覆盖它。

Python 3.9及以上版本

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

Python 3.8及以下版本

我推荐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_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')

简单快捷,但仅适用于参数0或1:

parser.add_argument("mybool", default=True,type=lambda x: bool(int(x)))
myargs=parser.parse_args()
print(myargs.mybool)

从终端调用后输出将为“False”:

python myscript.py 0

类似的用法是:

feature.add_argument('--feature',action='store_true')

如果你在命令中设置参数-feature

 command --feature

参数将为True,如果你不设置type -feature参数默认为False!

您可以创建一个BoolAction,然后使用它

class BoolAction(Action):
    def __init__(
            self,
            option_strings,
            dest,
            nargs=None,
            default: bool = False,
            **kwargs,
    ):
        if nargs is not None:
            raise ValueError('nargs not allowed')
        super().__init__(option_strings, dest, default=default, **kwargs)

    def __call__(self, parser, namespace, values, option_string=None):
        input_value = values.lower()
        b = input_value in ['true', 'yes', '1']
        if not b and input_value not in ['false', 'no', '0']:
            raise ValueError('Invalid boolean value "%s".)
        setattr(namespace, self.dest, b)

然后在parser.add_argument()中设置action=BoolAction

下面是另一种变体,没有额外的行/秒来设置默认值。布尔值总是被赋值,这样它就可以在逻辑语句中使用,而无需事先检查:

import argparse
parser = argparse.ArgumentParser(description="Parse bool")
parser.add_argument("--do-something", default=False, action="store_true",
                    help="Flag to do something")
args = parser.parse_args()

if args.do_something:
     print("Do something")
else:
     print("Don't do something")

print(f"Check that args.do_something={args.do_something} is always a bool.")