Argparse 不解析布尔参数?

Mak*_*gan 9 python command-line arguments argparse

我正在尝试制作这样的构建脚本:

import glob
import os
import subprocess
import re
import argparse
import shutil

def create_parser():
    parser = argparse.ArgumentParser(description='Build project')

    parser.add_argument('--clean_logs', type=bool, default=True,
                        help='If true, old debug logs will be deleted.')

    parser.add_argument('--run', type=bool, default=True,
                        help="If true, executable will run after compilation.")

    parser.add_argument('--clean_build', type=bool, default=False,
                        help="If true, all generated files will be deleted and the"
                        " directory will be reset to a pristine condition.")

    return parser.parse_args()


def main():
    parser = create_parser()
    print(parser)
Run Code Online (Sandbox Code Playgroud)

然而,无论我如何尝试传递参数,我都只能得到默认值。我总是得到Namespace(clean_build=False, clean_logs=True, run=True)

我努力了:

python3 build.py --run False
python3 build.py --run=FALSE
python3 build.py --run FALSE
python3 build.py --run=False
python3 build.py --run false
python3 build.py --run 'False'
Run Code Online (Sandbox Code Playgroud)

总是一样的事情。我缺少什么?

Ide*_* O. 16

您误解了如何argparse理解布尔参数。

基本上,您应该使用action='store_true'oraction='store_false'代替默认值,并理解不指定参数会给您带来相反的操作,例如

parser.add_argument('-x', type=bool, action='store_true')
Run Code Online (Sandbox Code Playgroud)

会引发:

python3 command -x
Run Code Online (Sandbox Code Playgroud)

x设置为True

python3 command
Run Code Online (Sandbox Code Playgroud)

x设置为False.

action=store_false会做相反的事情。


设置bool为类型的行为与您预期的不同,这是一个已知问题

当前行为的原因是type预期它是一个可调用的,用作argument = type(argument). bool('False')计算结果为,因此您需要为您期望发生的行为True设置不同的值。type

  • 我必须删除“类型”参数才能使其正常工作。像这样: ```parser.add_argument("-Var1", action="store_true")``` 因为 ```parser.add_argument("-Var1", type=bool, action="store_true")```导致错误。 (3认同)

rok*_*rok 5

参数run被初始化为True即使你通过--run False

基于这个伟大答案的以下代码是解决此问题的方法:

import argparse

def str2bool(v):
    if isinstance(v, bool):
        return v
    if v.lower() in ('yes', 'true', 't', 'y', '1'):
        return True
    elif v.lower() in ('no', 'false', 'f', 'n', '0'):
        return False
    else:
        raise argparse.ArgumentTypeError('Boolean value expected.')

def main():
    ap = argparse.ArgumentParser()
    # List of args
    ap.add_argument('--foo', type=str2bool, help='Some helpful text')
    # Importable object
    args = ap.parse_args()
    print(args.foo)


if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)