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


当前回答

最简单的方法是使用选项:

parser = argparse.ArgumentParser()
parser.add_argument('--my-flag',choices=('True','False'))

args = parser.parse_args()
flag = args.my_flag == 'True'
print(flag)

没有传递——my-flag的值为False。如果您总是希望用户显式地指定一个选项,则可以添加required=True选项。

其他回答

简单快捷,但仅适用于参数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

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

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.")

作为对@Akash Desarda的回答的改进,你可以这样做

import argparse
from distutils.util import strtobool

parser = argparse.ArgumentParser()
parser.add_argument("--foo", 
    type=lambda x:bool(strtobool(x)),
    nargs='?', const=True, default=False)
args = parser.parse_args()
print(args.foo)

它支持python test.py——foo

(base) [costa@costa-pc code]$ python test.py
False
(base) [costa@costa-pc code]$ python test.py --foo 
True
(base) [costa@costa-pc code]$ python test.py --foo True
True
(base) [costa@costa-pc code]$ python test.py --foo False
False

对于type=bool和type='bool'可能意味着什么,似乎存在一些混淆。一个(或两个)应该意味着'运行函数bool(),还是'返回布尔值'?type='bool'没有任何意义。Add_argument给出了一个'bool'不可调用的错误,与使用type='foobar'或type='int'时相同。

但argparse确实有注册表,允许你这样定义关键字。它主要用于动作,例如:action = store_true”。你可以看到注册的关键字:

parser._registries

它显示了一个字典

{'action': {None: argparse._StoreAction,
  'append': argparse._AppendAction,
  'append_const': argparse._AppendConstAction,
...
 'type': {None: <function argparse.identity>}}

这里定义了许多操作,但只有一种类型,即默认的argparse.identity。

这段代码定义了一个'bool'关键字:

def str2bool(v):
  #susendberg's function
  return v.lower() in ("yes", "true", "t", "1")
p = argparse.ArgumentParser()
p.register('type','bool',str2bool) # add type keyword to registries
p.add_argument('-b',type='bool')  # do not use 'type=bool'
# p.add_argument('-b',type=str2bool) # works just as well
p.parse_args('-b false'.split())
Namespace(b=False)

没有记录Parser.register(),但也没有隐藏。在大多数情况下,程序员不需要知道它,因为类型和动作需要函数值和类值。在stackoverflow中有许多为两者定义自定义值的示例。


如果从前面的讨论中不明显,bool()并不意味着“解析字符串”。来自Python文档:

bool(x):使用标准真值测试程序将值转换为布尔值。

对比一下

int(x):将数字或字符串x转换为整数。

我找到了一个很好的方法来存储参数的默认值为False,当它出现在命令行参数时,它的值应该为true。

cmd命令 当你想要论证为真时: Python main.py——csv

当你想要你的论点为假时: python main.py

import argparse
from ast import parse
import sys
parser = argparse.ArgumentParser(description='')
parser.add_argument('--csv', action='store_true', default = False 
,help='read from csv')
args = parser.parse_args()

if args.csv:
    print('reading from csv')