【问题标题】:Argparse not parsing boolean arguments?Argparse 不解析布尔参数?
【发布时间】:2020-07-14 21:51:09
【问题描述】:

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

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)

但是,无论我如何尝试传递参数,我都只能得到默认值。我总是收到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'

总是一样的。我错过了什么?

【问题讨论】:

标签: python command-line arguments argparse


【解决方案1】:

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

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

parser.add_argument('-x', type=bool, action='store_true')

会导致:

python3 command -x

x 设置为True

python3 command

x 设置为False

action=store_false 会做相反的事情。


bool 设置为类型的行为与您预期的不同,这是known issue

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

【讨论】:

  • 最近的一个错误/问题bugs.python.org/issue37564 发现 distutils.util.strtobool 可以将各种是/否(仅限英文)单词解析为真/假值。
【解决方案2】:

即使你传递了--run False,参数run 也会被初始化为True

以下基于great 答案的代码是解决此问题的方法:

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()

【讨论】:

    猜你喜欢
    • 2013-02-07
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 2021-07-13
    • 2015-11-08
    • 2014-03-04
    相关资源
    最近更新 更多