Argparse 可选布尔值
Argparse optional boolean
我正在尝试获得以下行为:
python test.py
⟹商店foo=False
python test.py --foo
⟹商店foo=True
python test.py --foo bool
⟹商店foo=bool
当我使用
时有效
parser.add_argument('--foo', nargs='?', default=False, const=True)
但是,如果我添加 type=bool
,它会中断,试图强制转换为布尔值。在这种情况下
python test.py --foo False
实际上最终存储 foo=True
。怎么回事??
对于布尔参数,您应该使用 action='store_true'
参数:
parser.add_argument('--foo', action='store_true')
所以没有--foo
选项:
python test.py
将导致 foo
参数的值为 False
,并且存在 --foo
选项:
python test.py --foo
将导致 foo
参数的值为 True
。
您确定您需要那个图案吗? --foo
和 --foo <value>
一起用于布尔开关,不是常用的模式。
至于您的问题,请记住命令行值为 字符串 并且 type=bool
表示您希望应用 bool(entered-string-value)
。对于 --foo False
,这意味着 bool("False")
,产生 True
;所有非空字符串都是真的!另见 。
我不支持 --foo
/ --foo <string value>
,我 强烈 建议你使用 --foo
来表示 True
,放弃参数值,而是添加 --no-foo
选项以显式设置 False
:
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
属性结束.
从 Python 3.9 开始,您还可以使用 argparse.BooleanOptionalAction
操作 class:
parser.add_argument("--foo", action=argparse.BooleanOptionalAction)
它会产生相同的效果,处理 --foo
和 --no-foo
来设置和清除标志。
如果您有一些其他配置机制将 foo
设置为 True
并且您需要使用命令行再次覆盖它,则您只需要一个 --foo / --no-foo
组合转变。 --no-<option>
是一种广泛采用的反转布尔命令行开关的标准。
如果您没有对--no-foo
反向开关的特定需求(因为只是省略了--foo
已经意味着 'false'),那么就坚持使用 action='store_true'
选项。这使您的命令行简单明了!
但是,如果您的用例或其他约束明确要求您的命令行 必须 有一些 --foo (true|false|0|1)
支持,那么请添加您自己的转换器:
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 <value>
的情况。
演示:
$ 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'
我正在尝试获得以下行为:
python test.py
⟹商店foo=False
python test.py --foo
⟹商店foo=True
python test.py --foo bool
⟹商店foo=bool
当我使用
时有效parser.add_argument('--foo', nargs='?', default=False, const=True)
但是,如果我添加 type=bool
,它会中断,试图强制转换为布尔值。在这种情况下
python test.py --foo False
实际上最终存储 foo=True
。怎么回事??
对于布尔参数,您应该使用 action='store_true'
参数:
parser.add_argument('--foo', action='store_true')
所以没有--foo
选项:
python test.py
将导致 foo
参数的值为 False
,并且存在 --foo
选项:
python test.py --foo
将导致 foo
参数的值为 True
。
您确定您需要那个图案吗? --foo
和 --foo <value>
一起用于布尔开关,不是常用的模式。
至于您的问题,请记住命令行值为 字符串 并且 type=bool
表示您希望应用 bool(entered-string-value)
。对于 --foo False
,这意味着 bool("False")
,产生 True
;所有非空字符串都是真的!另见
我不支持 --foo
/ --foo <string value>
,我 强烈 建议你使用 --foo
来表示 True
,放弃参数值,而是添加 --no-foo
选项以显式设置 False
:
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
属性结束.
从 Python 3.9 开始,您还可以使用 argparse.BooleanOptionalAction
操作 class:
parser.add_argument("--foo", action=argparse.BooleanOptionalAction)
它会产生相同的效果,处理 --foo
和 --no-foo
来设置和清除标志。
如果您有一些其他配置机制将 foo
设置为 True
并且您需要使用命令行再次覆盖它,则您只需要一个 --foo / --no-foo
组合转变。 --no-<option>
是一种广泛采用的反转布尔命令行开关的标准。
如果您没有对--no-foo
反向开关的特定需求(因为只是省略了--foo
已经意味着 'false'),那么就坚持使用 action='store_true'
选项。这使您的命令行简单明了!
但是,如果您的用例或其他约束明确要求您的命令行 必须 有一些 --foo (true|false|0|1)
支持,那么请添加您自己的转换器:
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 <value>
的情况。
演示:
$ 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'