关于python:Argparse可选布尔值

Argparse optional boolean

本问题已经有最佳答案,请猛点这里访问。

我正在尝试以下行为:

  • python test.py=>存储foo=false
  • python test.py--foo=>存储foo=true
  • python test.py--foo bool=>store foo=bool

它在我使用时起作用

1
    parser.add_argument('--foo',nargs='?', default=False, const=True)

但是,如果我添加type=bool,试图强制强制强制转换为布尔值,它就会中断。在这种情况下

1
python test.py --foo False

实际上最终存储的是foo=True。发生什么事??


你确定你需要那个图案吗?--foo--foo 合在一起,对于布尔交换来说,不是一种常用的模式。

关于您的问题,请记住命令行值是一个字符串,并且,type=bool表示您希望应用bool(entered-string-value)。对于--foo False,这意味着bool("False"),生成True;所有非空字符串都是真的!明白为什么argparse没有正确解析我的布尔标记吗?也。

我强烈建议你用--foo来表示True,去掉参数值,加上--no-foo选项来显式设置False,而不是支持--foo/--foo

1
2
parser.add_argument('--foo', default=False, action='store_true')
parser.add_argument('--no-foo', dest='foo', action='store_false')

--no-foo开关上的dest='foo'加法确保它存储的False值(通过store_false结束于同一args.foo属性。

如果有其他配置机制可以将foo设置为True,您只需要--foo / --no-foo组合,并且需要用命令行开关再次覆盖它。--no-是一种广泛采用的标准,用于反转布尔型命令行开关。

如果您不需要--no-foo反转开关(因为省略--foo就意味着"错误"),那么只需坚持action='store_true'选项。这使您的命令行保持简单和清晰!

但是,如果您的用例或其他约束特别要求您的命令行必须有一些--foo (true|false|0|1)支持,那么添加您自己的转换器:

1
2
3
4
5
6
7
8
9
10
def str_to_bool(value):
    if isinstance(value, bool):
        return value
    if value.lower() in {'false', 'f', '0', 'no', 'n'}:
        return False
    elif value.lower() in {'true', 't', '1', 'yes', 'y'}:
        return True
    raise ValueError(f'{value} is not a valid boolean value')

parser.add_argument('--foo', type=str_to_bool, nargs='?', const=True, default=False)
  • const值用于省略参数值的nargs='?'参数。在这里,当使用--foo时,设置foo=True
  • 开关完全不使用时,使用default=False
  • type=str_to_bool用于处理--foo 案件。

演示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ cat so52403065.py
from argparse import ArgumentParser

parser = ArgumentParser()

def str_to_bool(value):
    if value.lower() in {'false', 'f', '0', 'no', 'n'}:
        return False
    elif value.lower() in {'true', 't', '1', 'yes', 'y'}:
        return True
    raise ValueError(f'{value} is not a valid boolean value')

parser.add_argument('--foo', type=str_to_bool, nargs='?', const=True, default=False)

print(parser.parse_args())
$ python so52403065.py
Namespace(foo=False)
$ python so52403065.py --foo
Namespace(foo=True)
$ python so52403065.py --foo True
Namespace(foo=True)
$ python so52403065.py --foo no
Namespace(foo=False)
$ python so52403065.py --foo arrbuggrhellno
usage: so52403065.py [-h] [--foo [FOO]]
so52403065.py: error: argument --foo: invalid str_to_bool value: 'arrbuggrhellno'


对于布尔参数,应使用action='store_true'参数:

1
parser.add_argument('--foo', action='store_true')

因此,缺少--foo期权:

1
python test.py

将导致foo参数的False值,以及--foo选项的存在:

1
python test.py --foo

会导致foo参数的True值。