argparse 参数解析
本文来自官方文档,了解下面这些,基本上就够了。
argparse 模块
概念
argparse 是 Python 标准库中推荐的命令行解析模块。在 linux 中,我们可以执行带有参数的命令:
ls -l
rm -rf
上面例子中,
-l, -rf
都是可选参数。
python中也可以做到给一个模块添加可选参数,来进行命令解析。
基础
prog.py
import argparse
parser = argparse.ArgumentParser() # 创建解析器对象
parser.parse_args() # 解析命令
写了这三行,一个简单的命令解析就做完了。
尽管我们没有添加任何参数,它依然自带了一个
--help
或-h
的参数。
执行效果:
$ python3 prog.py --help
usage: prog.py [-h]
options:
-h, --help show this help message and exit
添加程序描述
import argparse
parser = argparse.ArgumentParser(description="Test ...") # 添加一个描述
args = parser.parse_args()
查看描述:
>>> python a.py --help
usage: a.py [-h]
Test ... # 这里能看到描述信息
optional arguments:
-h, --help show this help message and exit
位置参数
可以像是python 函数中的位置参数一样,我们指定一个位置参数,可以直接给脚本传递值,而不用指定参数名称
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int, help="display a square of a given number")
args = parser.parse_args() # 解析后返回一个对象,它包含了所有的参数
print(args.square) # 每个参数都是它的属性
add_argument()
可以添加一个参数,它的help
可以添加一个参数的提示信息,type
可以指定当前参数的类型(默认类型是字符串)
parser.parse_args()
返回一个包含所有参数的对象,每个参数都是它的属性。
使用:
$ python3 prog.py 4
4
可以看出,我们直接像位置参数一样,传递个值就行。
可选参数
可选参数,就是加不加都行的参数,类似于 linux 上的 ls -l
,-l
就是可选的。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbosity", help="increase output verbosity") # 使用 `--` 来指明可选项
args = parser.parse_args()
if args.verbosity:
print("verbosity turned on")
如果用户没有添加这一可选参数,相关的变量被赋值为 None
使用方式:
python prog.py --verbosity 4
短选项
可以给参数设置短选项,譬如默认的 -h
等同于 --help
, -h
就是一个短选项
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", help="increase output verbosity", # 使用 `-` 来指明短选项
action="store_true")
args = parser.parse_args()
if args.verbose:
print("verbosity turned on")
使用:
python3 prog.py -v
互斥选项
互斥选项,就是说两个选项互斥,用户只能使用其中一个。
import argparse
parser = argparse.ArgumentParser()
# 互斥分组
group = parser.add_mutually_exclusive_group()
# 分组中添加参数
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
# 正常的参数
parser.add_argument("x", type=int, help="the base")
args = parser.parse_args()
if args.quiet:
print('quiet is true')
elif args.verbose:
print('verbose is true')
使用:
>>> python a.py -v 2 # 单独某个互斥选项,搭配位置参数
verbose is true
>>> python a.py -q 2
quiet is true
>>> python a.py -q -v 2 # 两个互斥选项不能一起使用。
usage: a.py [-h] [-v | -q] x
a.py: error: argument -v/--verbose: not allowed with argument -q/--quiet
parse_args()
parse_args 也可以接受参数,它接收的是命令行参数列表。它的默认参数是 sys.argv[1:]
也就是用户执行脚本时附带的参数们。但其实我们也可以手动给它传递参数,列表的每个元素都是用户应该输入的参数:
test.py
import argparse
import sys
parser = argparse.ArgumentParser()
parser.add_argument("p", type=int, help="display a square of a given number")
parser.add_argument("-s", type=int)
parser.add_argument("-d", type=int, nargs=2)
args = parser.parse_args(["1", '-d', "2", "3", '-s', "4"]) # 等同于以脚本执行: python x.py 1 -d 2 3 -s 4
print(args)
print(sys.argv[1:])
我们在命令行中执行:
>>> python a.py 1 -d 2 3 -s 4
Namespace(p=1, s=4, d=[2, 3])
['1', '-d', '2', '3', '-s', '4']
add_argument 的常用参数
const 参数
const 参数用来保存一个常数。需要搭配 action
参数使用,当用户输入值时,系统不会保存用户输入的值,而是使用当前 const 的值。
action 参数
action="store"
这是动作的默认参数,也就是存储用户输入的值。
action="store_true"
store_true 可以让一个选项不接受赋值。如果用户在命令行使用了这个选项,就会将此选项值设置成 True,否则 False。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", help="increase output verbosity", action="store_true"),
args = parser.parse_args()
if args.verbose:
print("verbosity turned on")
add_argument()
的action
参数可以指定存放的动作
action="store_true"
意味着:当用户在命令行使用这个选项时,args.verbose=True
,否则为False
。并且这个参数不能设置值,否则会报错使用示例:
$ python3 prog.py --verbose # 仅仅使用这个选项,没赋值 verbosity turned on $ python3 prog.py --verbose 1 # 赋值会报错 usage: prog.py [-h] [--verbose] prog.py: error: unrecognized arguments: 1
action="store_false"
同 store_true.
action="count"
可以统计某个参数出现的次数。同样的,当前参数不接受赋值,仅仅统计当前参数的使用次数。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbosity", action="count",
help="increase output verbosity")
args = parser.parse_args()
print(args.verbosity)
使用:
>>> python a.py -v -v # 使用了2次
2
>>> python a.py -vvv
3
>>> python a.py -v 2 # 不接受赋值
usage: a.py [-h] [-v]
a.py: error: unrecognized arguments: 2
action="store_const"
存储被 const 命名参数指定的值
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
>>> parser.parse_args(['--foo'])
Namespace(foo=42)
当用户使用了这个参数
--foo
,会将const
存放的值,作为参数的值。
action='append'
将当前参数的值,添加到当前参数的列表中
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])
action='append_const'
将 const 指定的值,添加到列表(注意 const 命名参数默认为 None
)
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--str', dest='types', action='append_const', const=str)
>>> parser.add_argument('--int', dest='types', action='append_const', const=int)
>>> parser.parse_args('--str --int'.split())
Namespace(types=[<class 'str'>, <class 'int'>])
action='version'
打印版本信息
>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--version', action='version', version='%(prog)s 2.0')
>>> parser.parse_args(['--version'])
PROG 2.0
action='extend'
这会仓储一个列表,将每个参数添加到列表中
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument("--foo", action="extend", nargs="+", type=str)
>>> parser.parse_args(["--foo", "f1", "--foo", "f2", "f3", "f4"])
Namespace(foo=['f1', 'f2', 'f3', 'f4'])
nargs 参数
这个参数,可以指定一个参数后面可以跟随几个值。
譬如:python xxx.py -v 1 2 3
这句代码中, -v
参数后面跟了3个值:1 2 3
,这三个值都属于 -v
,我们就可以通过 nargs
定义一个参数后面可以跟随几个值。
nargs 的几种参数类型:
-
num
: num 是一个整数,它会将命令行中的 num 个参数放到一个列表中。 -
?
: 一个参数可以跟随值,也可以不跟随值(默认 default) -
*
: 一个参数后面可以跟随任意多的值,会放到列表中 -
+
: 一个参数后面必须跟随最少一个值,会放到列表中
示例一:
import argparse
parser = argparse.ArgumentParser(description="Test ...")
parser.add_argument('-v', '--verbose', nargs='?', default=0)
args = parser.parse_args()
print(args.verbose)
PS C:\Users\UNCO9CA\Desktop> python a.py -v # 没跟随值,None None PS C:\Users\UNCO9CA\Desktop> python a.py # 没加参数,默认 default 0 PS C:\Users\UNCO9CA\Desktop> python a.py -v 2 2
示例二:
import argparse
parser = argparse.ArgumentParser(description="Test ...")
parser.add_argument('-v', '--verbose', nargs='*', default=0)
parser.add_argument('x') # 位置参数
args = parser.parse_args()
print(args.verbose)
PS C:\Users\UNCO9CA\Desktop> python a.py 2 -v 1 2 3 4 # 可以将位置参数放到前面,然后后面所有的值都属于 -v ['1', '2', '3', '4']
type 参数
type 参数可以将用户输入的内容,做类型转换
import argparse
import pathlib
parser = argparse.ArgumentParser()
parser.add_argument('count', type=int)
parser.add_argument('distance', type=float)
parser.add_argument('street', type=ascii)
parser.add_argument('code_point', type=ord)
parser.add_argument('source_file', type=open)
parser.add_argument('dest_file', type=argparse.FileType('w', encoding='latin-1'))
parser.add_argument('datapath', type=pathlib.Path)
文件操作示例:
import argparse
parser = argparse.ArgumentParser(description="Test ...")
parser.add_argument('file', type=argparse.FileType('w', encoding='utf-8'))
args = parser.parse_args()
args.file.write('hello world')
python a.py './a.txt' # 会创建一个文件,然后写入内容
required 参数
required=True
可以指定一个参数为必填参数。
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', required=True)
>>> parser.parse_args(['--foo', 'BAR'])
Namespace(foo='BAR')
>>> parser.parse_args([])
usage: [-h] --foo FOO
: error: the following arguments are required: --foo
choices 参数
choices 选项,可以让限制用户的输入,让用户只能输入 choice 的内容之一,如果输入别的内容,会报错。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
help="increase output verbosity")
args = parser.parse_args()
default 参数
default 可以设置一个参数的默认值(不设置的话,如果用户不加此参数,此参数值默认是 None)
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbosity", action="count", default=0)
args = parser.parse_args()
dest 参数
我们上面都是这么用的:
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
help="increase output verbosity")
args = parser.parse_args()
print(args.verbosity) # 注意这里:verbosity 是 args 对象的属性
args
对象的默认属性名称:
-
如果是位置参数,直接使用位置参数的字符串作为属性名
-
如果是可选参数,通常把 长选项 的
--
除掉后的字符串,作为属性名:'--verbosity' -> 'verbosity'
; 如果没有长选项,只有短选项,则把短选项前面的-
去掉作为属性名。
但是我们还可以通过 dest 参数,手动设定属性名(只能给可选参数手动设置)
import argparse
parser = argparse.ArgumentParser(description="Test ...")
parser.add_argument('-x', dest='my_x')
args = parser.parse_args()
print(args.my_x)
>>> python a.py -x 12 12
metavar
当使用 python xx.py --help
时,仅仅改变参数的显示名字,不改变参数的调用方式
原因:
import argparse
parser = argparse.ArgumentParser(description="Test ...")
parser.add_argument('-x', dest='my_x') # 这里 dest 是小写的 `my_x`
args = parser.parse_args()
print(args.my_x)
PS C:\Users\UNCO9CA\Desktop> python a.py -h usage: a.py [-h] [-x MY_X] Test ... optional arguments: -h, --help show this help message and exit -x MY_X # 这里是大写的 `MY_X`
可以看出,我们定义的属性名:
my_x
是小写的,并且调用时也是使用的小写:args.my_x
但是使用
-h
显示信息时,是大写的MY_X
,这和实际情况不一致,因此我们需要修改一下-h
时显示的帮助信息
改变后:
import argparse
parser = argparse.ArgumentParser(description="Test ...")
parser.add_argument('-x', dest='my_x', metavar='my_x') # 添加 metavar
args = parser.parse_args()
print(args.my_x)
PS C:\Users\UNCO9CA\Desktop> python a.py -h usage: a.py [-h] [-x my_x] Test ... optional arguments: -h, --help show this help message and exit -x my_x # 小写了