我想使用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”,和他们的小写变体为假?
我认为更规范的做法是:
command --feature
and
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?
最简单和最正确的方法是:
from distutils.util import strtobool
parser.add_argument('--feature', dest='feature',
type=lambda x: bool(strtobool(x)))
请注意,True值是y, yes, t, True, on和1;
假值为n, no, f, False, off和0。如果val为其他值,则引发ValueError。
您可以创建一个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