当前位置: 代码网 > it编程>前端脚本>Python > Python命令行参数解析:argparse基本用法与常见坑

Python命令行参数解析:argparse基本用法与常见坑

2026年09月22日 Python 我要评论
1、简介argparse是python的标准库模块之一,用于在命令行接口中处理参数和选项。使得python脚本可以接收用户输入的参数和选项,用于控制程序的行为。与sys.argv的区别1)sys.ar

1、简介

argparse是python的标准库模块之一,用于在命令行接口中处理参数和选项。使得python脚本可以接收用户输入的参数和选项,用于控制程序的行为。

与sys.argv的区别

1)sys.argv获取的命令行参数,参数需要手动解析,开发者需要自己编写代码来处理参数的解析、验证和错误处理。

2)argparse相比sys.argsv,argparse 更加强大,适合用于复杂的命令行参数解析,能大大减少手动解析和错误处理的负担,并提供自动化的帮助和验证功能。

2、基本用法

以下是 argparse 的基本使用步骤:

  • 导入模块:导入 argparse。
  • 创建解析器:使用 argparse.argumentparser() 创建一个解析器对象。
  • 添加参数:通过 add_argument() 方法向解析器添加参数。
  • 解析参数:使用 parse_args() 方法解析传入的命令行参数。
  • 使用参数:通过访问解析结果对象的属性来使用参数。

示例:

import argparse

def get_args():
    # 创建 argumentparser 对象
    parser = argparse.argumentparser(description="示例 python 脚本使用 argparse 解析命令行参数")

    # 添加参数
    parser.add_argument('name', type=str, help='你的名字')  # 必须的参数
    parser.add_argument('-a', '--age', type=int, default=20, help='你的年龄(可选,默认20)')  # 可选参数
    parser.add_argument('-v', '--verbose', action='store_true', help='详细模式')  # 布尔开关

    # 解析命令行参数
    args = parser.parse_args()
    # 使用解析的参数
    print(f"你好, {args.name}!")
    print(f"你的年龄是: {args.age}")

    if args.verbose:
        print("详细模式已开启。")


if __name__ == '__main__':
    get_args()

假设上面的代码保存在一个文件 example.py 中,你可以在命令行中运行以下命令:

python example.py zhangsan -a 30 --verbose

输出结果:

你好, zhangsan!
你的年龄是: 21
详细模式已开启。

3、详细讲解每个部分

3.1 创建argumentparser 对象

argparse 模块对命令行接口的支持是基于 argparse.argumentparser 的实例建立的。

parser = argparse.argumentparser(
					description="示例 python 脚本使用 argparse 解析命令行参数",
				    formatter_class=argparse.argumentdefaultshelpformatter )
  • description:这个参数简要描述这个程序做什么以及怎么做。当用户使用 -h 或 --help 时显示。
  • formatter_class:这个参数指定特定的格式化类来自定义帮助信息的格式。

目前,有四种这样的类:

class argparse.rawdescriptionhelpformatter
class argparse.rawtexthelpformatter
class argparse.argumentdefaultshelpformatter¶
class argparse.metavartypehelpformatter

一般使用:argumentdefaultshelpformatter 自动添加默认的值的信息到每一个帮助信息的参数中。

3.2 添加参数

解析器对象通过调用 add_argument() 方法添加程序参数信息。这些调用指定 argumentparser 对象如何获取命令行字符串并将其转换为对象。

1)语法:

argumentparser.add_argument(name or flags…[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest]) 定义单个的命令行参数应当如何解析。

2)位置参数

parser.add_argument('name', type=str, help='你的名字')

位置参数:如果指定了位置参数,在命令行参数中是必填项,直接写在脚本之后。

3)可选参数

parser.add_argument('-a', '--age', type=int, default=20, help='你的年龄(可选,默认20)')

可选参数:在命令行中参数名以 - 或 – 开头;所谓可选是指在命令行可指定参数或者不指定。如果不指定则使用默认值,由default 参数提供默认值。

4)参数说明

name or flags - 用于定义参数的名称或标志;位置参数(必填),可选参数(带前缀 - 或 --),示例:

parser.add_argument('filename')       # 位置参数
parser.add_argument('-v', '--verbose') # 可选参数

type - 指定命令行参数应当被转换成的类型或转换函数,常见类型有 int、float、str,示例:

parser.add_argument('--count', type=int)  # 将输入值转换为整数

default - 指定参数的默认值,如果不指定参数则使用默认值,示例:

parser.add_argument('--age', type=int, default=18)  # 默认值为 18

help - 提供参数的帮助说明,在 --help 或 -h 选项中显示,示例:

parser.add_argument('--verbose', help='启用详细模式')  # 提供参数的帮助信息

required - 指定参数是否是必需的,通常用于可选参数(required=true),示例:

parser.add_argument('--output', required=true)  # 必须提供 --output 参数

action - 指定了这个命令行参数应当如何处理,将命令行参数与动作相关联,大多数动作只是简单的向 parse_args() 返回的对象上添加属性。常见的动作有:

  • ‘store’(默认):存储参数的值。示例
parser = argparse.argumentparser()
parser.add_argument('--foo')
parser.parse_args('--foo 1'.split())
# 结果:namespace(foo='1')

将参数和值存储到namespace对象中

  • ‘store_const’:存储 由 const 关键字参数指定的值(通常与 nargs=‘?’ 一起使用)。常用于指定某类flag的可选参数。示例:
parser = argparse.argumentparser()
parser.add_argument('--foo', action='store_const', const=42)
parser.parse_args(['--foo'])
namespace(foo=42)
  • ‘store_true’ 和 ‘store_false’ - 这是 ‘store_const’ 动作分别用作存储 true 和 false 值的特殊用例。另外,它们的默认值分别为 true和false。常用于布尔开关
  • ‘append’ - 存储一个列表,并将每个参数值添加到该列表。它适用于允许可多次指定的选项。 如果默认值非空,则默认的元素将出现在该选项的已解析值中,并将所有来自命令行的值添加在默认值之后。
parser = argparse.argumentparser()
parser.add_argument('--foo', action='append')
parser.parse_args('--foo 1 --foo 2'.split())
namespace(foo=['1', '2'])

nargs - 指定参数的个数,支持的符号:

  • n(一个整数)。接收参数的数量,命令行中的 n 个参数会被聚集到一个列表中。 例如:
parser = argparse.argumentparser()
parser.add_argument('--range', nargs=2)
parser.add_argument('bar', nargs=1)
parser.parse_args('c --range 1 10'.split())
namespace(bar=['c'], foo=['1', '10'])

注意 nargs=1 会产生一个单元素列表。这和默认的元素本身是不同的。

  • ‘?’:可选一个参数,没有时使用 const 值。
parser = argparse.argumentparser()
parser.add_argument('--foo', nargs='?', const='c', default='d')
parser.add_argument('bar', nargs='?', default='d')
parser.parse_args(['xx', '--foo', 'yy'])
namespace(bar='xx', foo='yy')
parser.parse_args(['xx', '--foo'])
namespace(bar='xx', foo='c')
parser.parse_args([])
namespace(bar='d', foo='d')
  • ‘*’: 接收零或多个参数,作为列表传递给参数。
parser = argparse.argumentparser()
parser.add_argument('--foo', nargs='*')
parser.add_argument('--bar', nargs='*')
parser.add_argument('baz', nargs='*')
parser.parse_args('a b --foo x y --bar 1 2'.split())
namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
  • ‘+’: 接收一个或多个参数,作为列表传递给参数。
parser = argparse.argumentparser(prog='prog')
parser.add_argument('foo', nargs='+')
parser.parse_args(['a', 'b'])
namespace(foo=['a', 'b'])

注意:如果没有给命令行参数传递至少一个值,会报错。

const - 当 action=‘store_const’ 或 nargs=‘?’ 时,指定参数的常量值。示例:

parser.add_argument('--level', nargs='?', const='medium', default='low')  # 没有参数时使用 'medium'

chioces - 指定参数值的允许范围或可选列表。示例:

parser.add_argument('--color', choices=['red', 'green', 'blue'])  # 只能选择 red, green, blue

dest: 指定存储参数值的属性名,该属性的名称由 add_argument() 的 dest 关键字参数确定,默认与参数名相同。

对于可选参数,dest 的值通常取自选项字符串。

argumentparser 会通过接受第一个长选项字符串并去掉开头的 -- 字符串来生成 dest 的值。

如果没有提供长选项字符串,则 dest 将通过接受第一个短选项字符串并去掉开头的 - 字符来获得。

参数名任何内部的 - 字符都将被转换为 _ 字符以确保字符串是有效的属性名称。

示例1:

parser = argparse.argumentparser()
parser.add_argument('-f', '--foo-bar', '--foo')
parser.add_argument('-x', '-y')
parser.parse_args('-f 1 -x 2'.split())
namespace(foo_bar='1', x='2')

示例2:

自定义属性名称

parser = argparse.argumentparser()
parser.add_argument('--foo', dest='bar')
parser.parse_args('--foo xxx'.split())
namespace(bar='xxx')

综合示例:

import argparse

# 创建 argumentparser 对象
parser = argparse.argumentparser(description="综合示例")

# 添加各种参数
parser.add_argument('filename', type=str, help='文件名')  # 位置参数
parser.add_argument('-v', '--verbose', action='store_true', help='启用详细模式')  # 布尔开关
parser.add_argument('--count', type=int, default=10, help='计数值(默认10)')  # 带默认值的参数
parser.add_argument('--level', choices=['low', 'medium', 'high'], help='选择级别')  # 限定选择值
parser.add_argument('--range', nargs=2, type=int, help='指定两个整数范围')  # 接收两个整数
parser.add_argument('--option', nargs='?', const='special', help='可选参数,没有时为 special')  # 带常量值的可选参数

# 解析命令行参数
args = parser.parse_args()

# 输出解析结果
print(f"文件名: {args.filename}")
print(f"详细模式: {args.verbose}")
print(f"计数值: {args.count}")
print(f"级别: {args.level}")
print(f"范围: {args.range}")
print(f"选项: {args.option}")

运行示例:

python script.py example.txt --verbose --count 5 --level high --range 10 20 --option

输出结果:

文件名: example.txt
详细模式: true
计数值: 5
级别: high
范围: [10, 20]
选项: special

3.3 解析参数

args = parser.parse_args(args=none, namespace=none)

解析传入的命令行参数并将其存储为 namespace对象的属性,返回值带有成员的namespace。

参数说明:

  • args - 要解析的字符串列表。 默认值是从 sys.argv 获取。
  • namespace - 用于获取属性的对象。 默认值是一个新的空 namespace 对象。

3.4 使用命令行参数

类似python对象使用内部属性一样,通过"."访问解析后的参数值。例如:

# 解析命令行参数
    args = parser.parse_args()
    # 使用解析的参数
    print(f"你好, {args.name}!")
    print(f"你的年龄是: {args.age}")

    if args.verbose:
        print("详细模式已开启。")

3.5 命名空间(argparse.namespace)

argparse.namespace 是 argparse 模块中的一个类,用于存储解析后的命令行参数。通过 argparse.argumentparser.parse_args() 方法解析参数后,会返回一个 namespace 对象,该对象的属性就是命令行参数的名称和值。

argparse.namespace 详解

  • namespace 对象的主要作用是将解析后的命令行参数以属性的形式存储,从而方便在程序中访问这些参数。
  • namespace 类本质上是一个简单的容器对象,类似于 python 的对象,可以动态地增加属性。

1、创建namespace对象

1)通过parser.parse_args()自动生成

2)手动创建namespace对象

from argparse import namespace

# 手动创建 namespace 对象
args = namespace(name='bob', age=30)

# 访问属性
print(args.name)  # 输出: bob
print(args.age)   # 输出: 30

3)将字典转换为namespace

from argparse import namespace

# 从字典创建 namespace
data = {'name': 'charlie', 'age': 28}
args = namespace(**data)

print(args)  # 输出: namespace(name='charlie', age=28)

2、namespace对象的常用操作

1)添加属性,动态添加属性

args = namespace()
args.name = 'david'
args.age = 40
print(args)  # 输出: namespace(name='david', age=40)

2)修改属性

args.age = 35
print(args)  # 输出: namespace(name='david', age=35)

3)删除属性

del args.name
print(args)  # 输出: namespace(age=35)

4)将 namespace 转换为字典:使用 vars() 函数将 namespace 对象转换为字典。

args_dict = vars(args)
print(args_dict)  # 输出: {'name': 'david', 'age': 35}

3.6 paser对象中的action对象

1、action对象定义

action(option_strings, dest, nargs=none, const=none, default=none, type=none, choices=none, required=false, help=none, metavar=none)

2、使用示例和解析

使用示例:

inference_args_dict = {}
    for action in parser._actions:
        inference_args_dict[action.dest] = action.default

解析:

1)action 对象会被 argumentparser 用来表示解析从命令行中的一个参数所必须的信息,也就是一个action对象包含一个add_argument() 方法添加的参数信息,每个 action 对象代表一个命令行参数,并包含有关该参数的各种信息,如名称、类型、默认值、帮助文本等。

2)parser 是一个 argumentparser 对象,_actions 是其内部的一个列表,包含所有由 add_argument() 方法添加的参数信息(即 action 对象)。

3)for action in parser._actions:这个循环遍历 parser._actions 列表中的每个 action 对象;所以action 在每次迭代中代表一个参数对象。

3、action对象的属性

1)dest 是 action 对象的一个属性,表示参数值在 namespace 对象中的存储名称,即解析后的参数值将保存在这个名称的属性中。

例如,如果使用 parser.add_argument(‘–age’, dest=‘user_age’),则 dest 将是 ‘user_age’。

2)default 是 action 对象的另一个属性,表示该参数的默认值(如果未在命令行中提供参数时使用的值)。

如果没有为参数指定默认值,default 通常为 none,除非在 add_argument() 中显式指定。

4、实际使用中遇到的坑

4.1 使用argparse获取命令行bool型参数

1)错误使用:

def get_args():
    parser = argparse.argumentparser(formatter_class=argparse.argumentdefaultshelpformatter)
    parser.add_argument('--is_test', type=bool, default=false,
                        help='是否使用测试模式')   
    args = parser.parse_args()
    return args

如果使用这种方式,会发现传递任何字符,args.is_test的结果都是true。因为python中非空字符串的bool值是true。

2)正确的使用方式:

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 get_args():
    parser = argparse.argumentparser(formatter_class=argparse.argumentdefaultshelpformatter)
    parser.add_argument('--is_test', type=str2bool, default=false,
                        help='是否使用测试模式')   
    args = parser.parse_args()
    return args

4.2 在程序中多次使用parser.parse_args()

导致意外行为,特别是在参数冲突或已经处理的参数被重新解析时。

如果你确实需要在程序中多次解析参数,一种有效的解决方案:

在整个程序中只调用一次parser.parse_args(), 后面使用parser对象来获取参数名和参数值。

def init_args():
    parser = argparse.argumentparser()
    # params for prediction engine 
    parser.add_argument("--gpu_mem", type=int, default=500)
    parser.add_argument("--gpu_id", type=int, default=0)
    return parser

def get_args():
    parser = argparse.argumentparser(formatter_class=argparse.argumentdefaultshelpformatter)
    parser.add_argument('--is_test', type=str2bool, default=false,
                        help='是否使用测试模式')   
    args = parser.parse_args()
    return args

def main():
	parser = init_args()
    inference_args_dict = {}
    for action in parser._actions:
        inference_args_dict[action.dest] = action.default
    args1 = argparse.namespace(**inference_args_dict)
    args = get_args()

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com