19、Python 命令行解析工具:argparse


一、argparse 简介

  • argparsepython 自带的命令行参数解析模块(它解析 sys.argv 中定义的参数),这个库可以让我们直接在命令行中就可以向程序中传入参数并让程序运行

  • 当你的代码需要频繁地修改参数的时候,使用这个工具可以将参数和代码分离开来,让你的代码更简洁,适用范围更广

  • 可分为如下四个步骤进行使用:

# 1、导入 argparse 包
import argparse

# 2、创建 ArgumentParser() 对象, description 是在参数帮助文档之前显示的文本
parser = argparse.ArgumentParser(description='Convert jpg images to SNPE model input.')

# 3、调用 add_argument() 方法添加参数
parser.add_argument('-i', '--input_dir', type=str, default='imgs/test_imgs', help='Input directory with jpg files.', )
parser.add_argument('-o', '--output_dir', type=str, default='imgs/raw_imgs', help='Output raw  file directory.')
parser.add_argument('-iw', '--img_w', type=int, default=128, help='img width')
parser.add_argument('-ih', '--img_h', type=int, default=48, help='img height')
# 多个输入的情况,使用 nargs='+',会自动组装成 list
parser.add_argument('-m', '--mean', type=float, nargs='+', default=[127.5, 127.5, 127.5], help='channel mean')
# argparse.REMAINDER:将剩余的参数值(转换成字符串)保存到一个 list 中, eg python 1-argparse.py --opts "SYSTEM.NUM_GPUS" 12 "TRAIN.SCALES" "(1, 2, 3, 4)"
# 输出 Namespace(opts=['SYSTEM.NUM_GPUS', '12', 'TRAIN.SCALES', '(1, 2, 3, 4)'])
parser.add_argument('-op', '--opts', nargs=argparse.REMAINDER, default="",
                    help="Modify config options using the command-line")
parser.add_argument('-s', '--scale', type=float, default=1.0, help='data scale')
parser.add_argument('-d', '--dim_order', type=str, default='hwc', help='chw or hwc')
parser.add_argument('-c', '--color_order', type=str, default='bgr', help='rgb or bgr')
parser.add_argument('-f', '--finetune', required=False, action='store_true', help='finetune model with distill')
# action 可以指定参数处理方式,默认是“store”代表存储的意思。如果使用"store_true", 表示他出现,那么对应参数为true,否则为false。
parser.add_argument('--foo', action='store_const', const=42)

# 4、使用 parse_args() 解析添加的参数:它将检查命令行,把每个参数转换为适当的类型然后调用相应的操作
# 当需要使用命令行参数时,使用 args.param(如:args.input_dir) 获取
args = parser.parse_args()  # 得到 argparse.Namespace object 类

print(args)  # 打印参数


# 可使用 python 1-argparse.py -h/--help 调出帮助文档
usage: 1-argparse.py [-h] [-i INPUT_DIR] [-o OUTPUT_DIR] [-iw IMG_W] [-ih IMG_H] [-m MEAN [MEAN ...]] [-op ...] [-s SCALE] [-d DIM_ORDER] [-c COLOR_ORDER] [-f]

Convert jpg images to SNPE model input.

optional arguments:
  -h, --help            show this help message and exit
  -i INPUT_DIR, --input_dir INPUT_DIR
                        Input directory with jpg files.
  -o OUTPUT_DIR, --output_dir OUTPUT_DIR
                        Output raw file directory.
  -iw IMG_W, --img_w IMG_W
                        img width
  -ih IMG_H, --img_h IMG_H
                        img height
  -m MEAN [MEAN ...], --mean MEAN [MEAN ...]
                        channel mean
  -op ..., --opts ...   Modify config options using the command-line
  -s SCALE, --scale SCALE
                        data scale
  -d DIM_ORDER, --dim_order DIM_ORDER
                        chw or hwc
  -c COLOR_ORDER, --color_order COLOR_ORDER
                        rgb or bgr
  -f, --finetune        finetune model with distill

二、argparse 使用

在这里插入图片描述

2.1、参数设置:name or flags

  • 参数可以是:位置参数、以 -- 开头的可选参数、以 --- 开头的可选参数;其中基本不使用位置参数,常使用后面两种参数
  • 位置参数默认是必填参数;可选参数默认是可选的,可通过 required=True 将其设置为必填参数
# name.py
import argparse
parser = argparse.ArgumentParser(description="Super Params Config") 

# 1、positional argument,默认是必填参数
parser.add_argument('file_extension') 

# 2、option that takes a value,默认是可选参数,可通过 required=True 将其设置为必填参数
parser.add_argument('-batch_size', type=int, default=64, required=True, help="batch size")

# 3、option that takes two values,默认是可选参数,可通过 required=True 将其设置为必填参数
parser.add_argument('-i', '--input_dir', type=str, default='imgs/test_imgs',
                    required=False, help='Input directory with jpg files.')

args = parser.parse_args() 

# 命令行使用方式
python name.py 'py' -i 'imgs/'
python name.py 'py' -i='imgs/'
python name.py 'py' --input_dir 'imgs/'
python name.py 'py' --input_dir='imgs/'

2.2、参数将会如何处理:action

action 命名参数指定了这个命令行参数应当如何处理?

  • 如果不给出命令行参数,则相应的参数得到的值是 None
  • 如果在命令行给出参数(只需提供 key 即可),则相应的参数得到的值是其存储的值;经常使用 store_true

在这里插入图片描述

# action.py

# 1、store_true 和 store_false 设置,默认值分别为 True 和 False
parser.add_argument('--foo', action='store_true')  # 如果命令行不给出,则为 False
parser.add_argument('--bar', action='store_false') # 如果命令行不给出,则为 True

# 1、store_true 和 store_false 命名行
python action.py --foo  # Namespace(foo=True, bar=True)
python action.py --foo --bar  # Namespace(foo=True, bar=False)

# 2、store_const 设置
parser.add_argument('--foo', action='store_const', const=42)

# 2、store_const 命名行
python action.py         # 输出 Namespace(foo=None)
python action.py --foo   # 输出 Namespace(foo=42)

# 3、append 用法
parser.add_argument('--foo', action='append')
parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])

# 4、extend 用法
parser.add_argument("--foo", action="extend", nargs="+", type=str)
parser.parse_args(["--foo", "f1", "--foo", "f2", "f3", "f4"])
Namespace(foo=['f1', 'f2', 'f3', 'f4'])

2.3、读取的命令行参数个数:nargs

在这里插入图片描述

# nargs.py
N: 参数的绝对个数(例如:3'?': 01 个参数
'*': 0 或所有参数
'+': 所有,并且至少一个参数
argparse.REMAINDER:将剩余的参数值保存到一个 list# 1、多个输入的情况(至少要输入一个参数),使用 nargs='+',会自动组装成 list
parser.add_argument('-m', '--mean', help='channel mean',
                    type=float, nargs='+', required=False, default=[127.5, 127.5, 127.5])

# 1、nargs='+' 命名行设置
python nargs.py --mean 128 128 128  # Namespace(mean=[128.0, 128.0, 128.0],)


# 2、argparse.REMAINDER:将剩余的参数值保存到一个 list 中
parser.add_argument("--opts", default="", nargs=argparse.REMAINDER,
                    help="Modify config options using the command-line")

# 2、argparse.REMAINDER 命名行设置(一般不需要额外的参数设置 opts,opts 后面的参数会转换为字符串后组合成列表)
python main.py --opts "SYSTEM.NUM_GPUS" 12 "TRAIN.SCALES" "(1, 2, 3, 4)"
# 输出 Namespace(opts=['SYSTEM.NUM_GPUS', '12', 'TRAIN.SCALES', '(1, 2, 3, 4)'])

2.4、命令行参数转换类型:type

  • type 指定了命令行参数应该被转换为何种类型,可以是 int、float、str、list、tuple
    在这里插入图片描述

2.5、参数值选择:choices

  • choices:参数值只能从给定的几个选项里面选择,可以有默认值
    在这里插入图片描述
# choices.py

# 多个输入的情况(至少要输入一个参数),使用 nargs='+',会自动组装成 list
parser.add_argument('-arch', type=str, choices=['alexnet', 'vgg'], default='alexnet')

# choices 命名行设置
python choices.py -arch vgg  # Namespace(arch='vgg',)

2.6、实际项目使用示例

# yolov6-v3.0

def boolean_string(s):
    if s not in {'False', 'True'}:
        raise ValueError('Not a valid boolean string')
    return s == 'True'



def get_args_parser(add_help=True):
    parser = argparse.ArgumentParser(description='YOLOv6 PyTorch Evalating', add_help=add_help)
    parser.add_argument('--data', type=str, default='./data/coco.yaml', help='dataset.yaml path')
    parser.add_argument('--weights', type=str, default='./weights/yolov6s.pt', help='model.pt path(s)')
    parser.add_argument('--batch-size', type=int, default=32, help='batch size')
    parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
    parser.add_argument('--conf-thres', type=float, default=0.03, help='confidence threshold')
    parser.add_argument('--iou-thres', type=float, default=0.65, help='NMS IoU threshold')
    parser.add_argument('--task', default='val', help='val, test, or speed')
    parser.add_argument('--device', default='0', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--half', default=False, action='store_true', help='whether to use fp16 infer')
    parser.add_argument('--save_dir', type=str, default='runs/val/', help='evaluation save dir')
    parser.add_argument('--name', type=str, default='exp', help='save evaluation results to save_dir/name')
    parser.add_argument('--test_load_size', type=int, default=640, help='load img resize when test')
    parser.add_argument('--letterbox_return_int', default=False, action='store_true', help='return int offset for letterbox')
    parser.add_argument('--scale_exact', default=False, action='store_true', help='use exact scale size to scale coords')
    parser.add_argument('--force_no_pad', default=False, action='store_true', help='for no extra pad in letterbox')
    parser.add_argument('--not_infer_on_rect', default=False, action='store_true', help='default to use rect image size to boost infer')
    parser.add_argument('--reproduce_640_eval', default=False, action='store_true', help='whether to reproduce 640 infer result, overwrite some config')
    parser.add_argument('--eval_config_file', type=str, default='./configs/experiment/eval_640_repro.py', help='config file for repro 640 infer result')
    parser.add_argument('--do_coco_metric', default=True, type=boolean_string, help='whether to use pycocotool to metric, set False to close')
    parser.add_argument('--do_pr_metric', default=False, type=boolean_string, help='whether to calculate precision, recall and F1, n, set False to close')
    parser.add_argument('--plot_curve', default=True, type=boolean_string, help='whether to save plots in savedir when do pr metric, set False to close')
    parser.add_argument('--plot_confusion_matrix', default=False, action='store_true', help='whether to save confusion matrix plots when do pr metric, might cause no harm warning print')
    parser.add_argument('--verbose', default=False, action='store_true', help='whether to print metric on each class')
    parser.add_argument('--config-file', default='', type=str, help='experiments description file, lower priority than reproduce_640_eval')
    args = parser.parse_args()

    if args.config_file:
        assert os.path.exists(args.config_file), print("Config file {} does not exist".format(args.config_file))
        cfg = Config.fromfile(args.config_file)
        if not hasattr(cfg, 'eval_params'):
            LOGGER.info("Config file doesn't has eval params config.")
        else:
            eval_params=cfg.eval_params
            for key, value in eval_params.items():
                if key not in args.__dict__:
                    LOGGER.info(f"Unrecognized config {key}, continue")
                    continue
                if isinstance(value, list):
                    if value[1] is not None:
                        args.__dict__[key] = value[1]
                else:
                    if value is not None:
                        args.__dict__[key] = value

    # load params for reproduce 640 eval result
    if args.reproduce_640_eval:
        assert os.path.exists(args.eval_config_file), print("Reproduce config file {} does not exist".format(args.eval_config_file))
        eval_params = Config.fromfile(args.eval_config_file).eval_params
        eval_model_name = os.path.splitext(os.path.basename(args.weights))[0]
        if eval_model_name not in eval_params:
            eval_model_name = "default"
        args.test_load_size = eval_params[eval_model_name]["test_load_size"]
        args.letterbox_return_int = eval_params[eval_model_name]["letterbox_return_int"]
        args.scale_exact = eval_params[eval_model_name]["scale_exact"]
        args.force_no_pad = eval_params[eval_model_name]["force_no_pad"]
        args.not_infer_on_rect = eval_params[eval_model_name]["not_infer_on_rect"]
        #force params
        #args.img_size = 640
        args.conf_thres = 0.03
        args.iou_thres = 0.65
        args.task = "val"
        args.do_coco_metric = True

    LOGGER.info(args)
    return args


if __name__ == "__main__":
    args = get_args_parser()
    main(args)

三、参考资料

1、https://docs.python.org/zh-cn/3/library/argparse.html
2、Python argparse 教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值