这是我在使用argparse时记的一些笔记,如有纰漏,请及时指出,感激不尽!
这篇博客的目的在于快速上手使用argparse模块,能够实现命令行传参。所以这篇博客不会对方法的各个参数进行解释,其中第一部分只介绍了最简单的使用方式,第二部分对一些内容进行补充说明。如果想要了解各个参数的具体分析,可以移步至Python文档。
目录
一、最简单的使用方式
首先,在使用该模块之前,需要明确位置参数和可选参数以及Namespace。简单来说,位置参数就是根据命令行中值的位置来对参数进行赋值;可选参数在传递值时,根据参数名称进行传递。而Namespace是一个很简单的类,解析器将参数存储在这个类中。
下面就开始使用模块。
导入模块:
import argparse
创建一个解析器:
parser = argparse.ArgumentParser(description='description')
一般来说,创建解析器的时候只会用到关键字参数description,是对该解析器的功能与作用进行解释与描述。
向模块中添加参数:
parser.add_argument('param1', type=int, help='input param1')
parser.add_argument('--param2', type=int, help='input param2')
有几点需要注意的地方,add_argument方法的第一个参数是你所定义的参数的名称,可以是一个或多个,在后续会进行展示。上面代码块中,param1是位置参数,param2是可选参数,定义可选参数时需要在参数前面加上'-'或者'--'。一般来说,'-'是在单字母时使用(但是不是必须这样做)。
type就是参数的类型,命令行一开始传入的都是字符串,add_argument会根据type定义的类型对传入的值进行转换。默认为str类型。
help是提示信息。
解析参数:
args = parser.parse_args()
访问参数:
args.param1
args.param2
到此最简单的使用方式已经介绍完毕,下面是在命令行中如何传入参数的示例。
命令行传参:
python xxx.py 5 --param2=6
其中xxx.py是解析器所在的py文件,第一个5是给位置参数传递值,第二个是给可选参数传递值(其中=可以用空格代替)。
二、补充说明
1. 为何要区分位置参数和可选参数
其实可以理解为函数传参,可选参数就是关键字参数,看下面两个代码块
# code1
parser.add_argument('param1', type=int, help='input param1')
parser.add_argument('param2', type=int, help='input param2')
# code2
parser.add_argument('param2', type=int, help='input param2')
parser.add_argument('param1', type=int, help='input param1')
如果命令行都为
python xxx.py 5 6
最终,是两个不同的结果
# code1
Namespace(param1=5, param2=6)
# code2
Namespace(param2=5, param1=6)
如果只针对代码块1,命令行分别为
python xxx.py 5 6
python xxx.py 6 5
结果为
# 1
Namespace(param1=5, param2=6)
# 2
Namespace(param1=6, param2=5)
2. 关于参数的名称
add_argument的传递的第一个参数是所定义的参数名称,可以是多个名称,也可以是单个名称。当需要多个名称时,该参数为可选参数。
parser.add_argument('-p', '--param', '--para', type=int, help='input param')
上述这些名称在命令行传参时都可以代表该参数,如:
python xxx.py -p 5
# 或
python xxx.py --param 5
# 或
python xxx.py --para 5
那就产生了一个问题,最终存储到Namespace中时,该参数的名称是哪一个呢?这就需要解释add_argument中的dest参数。
dest参数简单来说就是规定了存储到Namespace中时,该参数的名称。
当dest未指定时,对于位置参数来说,就是使用add_argument的第一个参数作为名称;对于可选参数来说,如果存在'--'开头的名称,那就以第一个'--'开头的名称作为dest的值,如果不存在'--'开头的名称,那么就使用第一个'-'开头的名称作为dest的值。(这段比较绕,可以具体看下面的例子)
例如:
# dest='param'
parser.add_argument('-p', '--param', '--para', type=int, help='input param')
# dest='para'
parser.add_argument('-p', '--para', '--param', type=int, help='input param')
# dest='p'
parser.add_argument('-p', type=int, help='input param')
还有一点需要注意的是,当指定了dest后 ,命令行传参时也可以使用dest所指定的参数名称进行传递。
除此之外,在传参时,默认还可以使用缩写进行传递,前提是,缩写不会与其他参数或者其他参数的缩写发生冲突。其实意思就是前缀匹配。
例如:
parser.add_argument('--perfect')
parser.add_argument('--perplexity')
命令行传参时,就可以为
python xxx.py --perf 5 --perp 6
# Namespace(perfect='5', perplexity='6')
但是如果缩写冲突了,那就会报错, 例如
python xxx.py --per 5
# usage: argparse_train.py [-h] [--perfect PERFECT] [--perplexity PERPLEXITY]
# argparse_train.py: error: ambiguous option: --per could match --perfect, --perplexity
3. 一个参数传入多个值
有时候,需要对一个参数传入多个值,以列表的形式存储,add_argument也可以实现,就是nargs。例如:
parser.add_argument('param', nargs='+')
nargs可以传入具体的参数个数,也可以传递特定的符号:'?', '*', '+'。符号所代表的含义如下:
- '?':允许传入一个值或者不传入值
- '*':允许传入多个值或者不传入值
- '+':至少需要传入一个值
命令行:
python xxx.py 1 2 3 4 5
# Namespace(param=['1', '2', '3', '4', '5'])
注意,针对于上面的情况,如果有多个位置参数的nargs为'+',并且命令行传入的值的个数大于参数的个数,那么只有第一个位置参数会被认为有多个值。例如:
parser.add_argument('param1', nargs='+')
parser.add_argument('param2', nargs='+')
parser.add_argument('param3', nargs='+')
python xxx.py 1 2 3 4 5
# Namespace(param1=['1', '2', '3'], param2=['4'], param3=['5'])
4. 默认参数与必须参数
默认参数的作用是当命令行中未指定该参数的值时,就使用默认参数。必须参数规定了哪些参数是必须要传递值的。例如:
parser.add_argument('--param1', required=True)
parser.add_argument('--param2', default='1')
python xxx.py --param1=3
# Namespace(param1='3', param2='1')
如果未对必须参数传递值:
python xxx.py --param1=3
# usage: argparse_train.py [-h] --param1 PARAM1 [--param2 PARAM2]
# argparse_train.py: error: the following arguments are required: --param1
注意,对于位置参数来说,只有当nargs='*'或'?'时,默认参数才起作用。
5. 互斥参数
顾名思义,互斥参数就是只有一个参数能够起作用或者都没有参数起作用。换句话说,就是只有一个参数能够有值或者所有参数都没有赋值。例如:
mutex = parser.add_mutually_exclusive_group()
mutex.add_argument('-t', '--true', action='store_true')
mutex.add_argument('-f', '--false', action='store_true')
args = parser.parse_args()
if args.true:
print('True')
elif args.false:
print('False')
else:
print('Nothing')
python xxx.py -t
# True
python xxx.py -f
# False
python xxx.py
# Nothing
python xxx.py -t -f
# usage: argparse_train.py [-h] [-t | -f]
# argparse_train.py: error: argument -f/--false: not allowed with argument -t/--true
6. action
上述互斥参数的代码块中可以看到action赋值为'store_true',那action有何作用?
action是对当前参数所做的动作,意思是该参数在命令行中出现时,会执行action动作,action的默认值为'store',即存储,就是将命令行中的值存储到Namespace中。以下是一些action的常用的可选值:
- 'store':将当前参数的值存储为命令行中指定的值
- 'store_const':将当前参数的值存储为const指定的值,命令行中不需传递值
- 'store_true' or 'store_false':将当前参数的值存储为'true'或者'false',命令行中不需传递值
- 'append':将当前参数的值存储为一个列表,并在命令行中后续出现该参数的值时,向列表的末尾append命令行中的值,命令行中需传递值
- 'append_const':以列表的形式存储该参数的值,并在命令行中后续出现该参数时,向列表的末尾append const所指定的值,命令行中不需传递值
- 'count':对命令行中出现该参数的个数进行计数
注意, 对于'append'来说,需要命令行中传递一个值,即使使用了default也需要传递。对于不需要传递值的action而言,即使设置了default也没有用,不会改变该参数的值。
action以及其他的详细说明请见Python文档。
如果该篇博客有任何错误,请各位大佬及时在评论区指出,我会及时进行修改,感激不尽。