• python中argparse模块关于 parse_args() 函数详解(全)


    前言

    • 原理:命令行解析使用argparse包
    • 作用:命令行传参赋值 可用在机器学习深度学习 或者 脚本运行等

    了解这个函数需要了解其背后的原理以及具体参数

    1. 函数讲解

    在深度学习模型框架中几乎都有的模块
    浓缩后的示例代码:

    # 导入模块包
    import argparse
    
    # 解析对象ArgumentParser,description程序描述
    parser=argparse.ArgumentParser(description=" parse_args() 函数讲解")
    
    # 对象值赋参(可选 或者 必选),指定该程序需要接受的命令参数
    parser.add_argument('--weights', default=ROOT / 'yolov5s.pt', help='model path or triton URL')
    
    # 增加后的属性赋值给args
    args=parser.parse_args()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    主要的对象值赋参,对应的参数具体如下:
    在这里插入图片描述
    主要有两种情况:

    • 位置参赋值:parser.add_argument("a",help="输出a值")
      执行位置参的赋值,对应命令行输入为:python detect.py 1,最后输出args.a = 1
    • 可选赋值:parser.add_argument('--weights', nargs='+', type=str, default=ROOT / 'yolov5s.pt', help='model path or triton URL')
      可选参数可选可不选
    参数大致情况
    action程序运行前的操作。结合可选参数bool(python detect.py --bool,默认action为store_true,则将其bool设置为1 )
    nargs接受的参数个数
    count参数出现的次数。结合action,比如 action="count"
    desault参数默认值
    type默认值为str,不是str值会被过滤。需要int类型,只需设置type = int
    choices参数可选值,比如choices=[0, 1, 2]
    required指定参数需要用到该值,比如required=True)
    help参数介绍
    metavar配合help将其信息输出
    dest关联值,若dest=“a”,那么可以通过args.a访问该参数
    version程序版本信息

    其源函数的逻辑代码如下(在argparse模块中,仅展示大致逻辑):
    关于函数中涉及的*args, **kwargs,可看我这篇文章:Python关于 *args 和 **kwargs 参数的详解(全)

        # =======================
        # Adding argument actions
        # =======================
        def add_argument(self, *args, **kwargs):
            """
            add_argument(dest, ..., name=value, ...)
            add_argument(option_string, option_string, ..., name=value, ...)
            """
    
            # 如果没有提供位置参数,或者只提供了一个,而且它看起来不像选项字符串,解析一个位置参数
            chars = self.prefix_chars
            if not args or len(args) == 1 and args[0][0] not in chars:
                if args and 'dest' in kwargs:
                    raise ValueError('dest supplied twice for positional argument')
                kwargs = self._get_positional_kwargs(*args, **kwargs)
    
            # 否则,我们将添加一个可选参数
            else:
                kwargs = self._get_optional_kwargs(*args, **kwargs)
    
            # 如果没有提供默认值,则使用解析器级别的默认值
            if 'default' not in kwargs:
                dest = kwargs['dest']
                if dest in self._defaults:
                    kwargs['default'] = self._defaults[dest]
                elif self.argument_default is not None:
                    kwargs['default'] = self.argument_default
    
            # 创建操作对象,并将其添加到解析器中
            action_class = self._pop_action_class(kwargs)
            if not callable(action_class):
                raise ValueError('unknown action "%s"' % (action_class,))
            action = action_class(**kwargs)
    
            # 如果操作类型不可调用,则引发错误
            type_func = self._registry_get('type', action.type, action.type)
            if not callable(type_func):
                raise ValueError('%r is not callable' % (type_func,))
    
            if type_func is FileType:
                raise ValueError('%r is a FileType class object, instance of it'
                                 ' must be passed' % (type_func,))
    
            # 如果元数据与类型不匹配,则引发错误
            if hasattr(self, "_get_formatter"):
                try:
                    self._get_formatter()._format_args(action, None)
                except TypeError:
                    raise ValueError("length of metavar tuple does not match nargs")
    
            return self._add_action(action)
    
    	# =======================
        # 对应函数代码调用
        # =======================
    
        def add_argument_group(self, *args, **kwargs):
            group = _ArgumentGroup(self, *args, **kwargs)
            self._action_groups.append(group)
            return group
    
        def add_mutually_exclusive_group(self, **kwargs):
    	## 省略
    
    	# =======================
        # 对应参数的赋值 初始化等
        # =======================
        
    class _ArgumentGroup(_ActionsContainer):
    
        def __init__(self, container, title=None, description=None, **kwargs):
            # 通过检查容器添加任何缺少的关键字参数
            update = kwargs.setdefault
            update('conflict_handler', container.conflict_handler)
            update('prefix_chars', container.prefix_chars)
            update('argument_default', container.argument_default)
            super_init = super(_ArgumentGroup, self).__init__
            super_init(description=description, **kwargs)
    
            # 属性
            self.title = title
            self._group_actions = []
    
            # 与容器共享大部分属性
            self._registries = container._registries
            self._actions = container._actions
            self._option_string_actions = container._option_string_actions
            self._defaults = container._defaults
            self._has_negative_number_optionals = \
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89

    2. 基本用法

    • 执行脚本,输出想要的值:python test1.py 2,最后输出值为4
    import argparse
    parser = argparse.ArgumentParser(description=" 输出平方数")
    parser.add_argument("square",type=int)
    args = parser.parse_args()
    # 输出args.square的值为4
    print args.square**2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 执行位置参数(将值赋值给参数):python test1.py 2,最后输出2
    import argparse
    parser = argparse.ArgumentParser(description=" 输出a值")
    parser.add_argument("a")
    args = parser.parse_args()
    # 输出a的值2
    print args.a
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3. 实战讲解

    以下运行的是yolov5的代码逻辑:

    整体的主函数为:

    if __name__ == "__main__":
    	# 解析命令行格式下的参数
        opt = parse_opt()
        # 调用主函数
        main(opt)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    对应命令行格式下的参数可以为图片或者视频流:python detect.py --source data/images/bus.jpg,代码运行截图如下:
    在这里插入图片描述

    具体解析参数的函数如下:

    def parse_opt():
       # 传入的参数,以上的参数为命令行赋值的参数,如果没有给定该参数值,会有一个default的默认值进行赋值
        parser = argparse.ArgumentParser()
        parser.add_argument('--weights', nargs='+', type=str, default=ROOT / 'yolov5s.pt', help='model path or triton URL')
        parser.add_argument('--source', type=str, default=ROOT / 'data/images', help='file/dir/URL/glob/screen/0(webcam)')
        parser.add_argument('--data', type=str, default=ROOT / 'data/coco128.yaml', help='(optional) dataset.yaml path')
        parser.add_argument('--imgsz', '--img', '--img-size', nargs='+', type=int, default=[640], help='inference size h,w')
    	
    	# 省略的参数(由于参数比较多,此处就不放入
    	
        opt = parser.parse_args()
        
        # 此处对传入的size加以判断。如果不传入,默认为640,则长度为1,则对应size 为640 * 640。如果传入的参数为640 * 640 ,则不修改
        opt.imgsz *= 2 if len(opt.imgsz) == 1 else 1  # expand
        # 将其所有的参数信息进行打印
        print_args(vars(opt)
        # 将其opt的参数返回,后续调用main函数需要调用该参数
        return opt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    具体main函数的执行如下:

    def main(opt):
    	# 检查requirement的依赖包 有无成功安装,如果没有安装部分会在此处报错
        check_requirements(exclude=('tensorboard', 'thop'))
        # 如果成功安装,将其所有的参数代入,并执行此处的run函数
        run(**vars(opt))
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    软件测试中的树莓酱定律
    linux 内核协助的探测
    SSM - Springboot - MyBatis-Plus 全栈体系(二十二)
    redis的配置文件
    [自制操作系统] 第07回 认识保护模式之地址映射
    Redis分布式锁
    Linux环境的Windows子系统
    java计算机毕业设计敬老院管理系统源码+数据库+系统+lw文档+mybatis+运行部署
    用Python实现广度优先搜索
    Docker 部署 RabbitMQ 集群
  • 原文地址:https://blog.csdn.net/weixin_47872288/article/details/127801655