Python 命令行参数解析
Python经常被用来写一下简化操作的脚本,并且要求脚本支持一定的选项,有必要整理一下Python命令行参数解析的用法。
Python自带的argparse
模块功能已经非常强大,使用非常便捷。
Python其实还有另外两个模块可以完成同样的任务:getopt
和optparse
,但是前者过于简单,后者已经被弃用,目前只推荐使用argparse
。
与之形成鲜明对比的是,C++对这种基础的需求通常都是直接手写的,或者去下载一些第三方提供的纯头文件库,为这种简单的任务引入外部依赖其实也并不合算,不如直接自己写了。
极简例子
从最简单的例子开始 1
2
3import argparse
parser = argparse.ArgumentParser()
parser.parse_args()
这两行的含义为:设置一个参数解析器,解析参数。
直接运行脚本,无事发生 1
python test.py
空的参数解析器为我们提供了--help
(-h
)参数,可以打印使用帮助,例如
1
python test.py -h
输出形如 1
2
3
4usage: test.py [-h]
options:
-h, --help show this help message and exit
基本使用
位置参数
我们可以添加位置参数,例如 1
2
3
4
5
6
7import argparse
parser = argparse.ArgumentParser()
parser.add_argument("op1")
parser.add_argument("op2")
args = parser.parse_args()
print("op1 =", args.op1)
print("op2 =", args.op2)
这里我们直接使用了args.op1
,这是argparse
直接提供的“魔法”:args
的成员名称由add_argument
传入的字符串决定。
我们从args
得到的也只是字符串,如果需要作为其它数据类型使用,需要手动进行类型转换。
使用例如 1
python test.py value1 value2
输出 1
2op1 = value1
op2 = value2
在加入了两个位置参数之后,使用帮助变成了 1
2
3
4
5
6
7
8usage: test.py [-h] op1 op2
positional arguments:
op1
op2
options:
-h, --help show this help message and exit
我们可以给选项加上描述 1
2
3
4
5
6
7import argparse
parser = argparse.ArgumentParser()
parser.add_argument("op1", help="op1 is xxx")
parser.add_argument("op2", help="op2 is yyy")
args = parser.parse_args()
print("op1 =", args.op1)
print("op2 =", args.op2)
这可以提升使用帮助的可读性 1
2
3
4
5
6
7
8usage: test.py [-h] op1 op2
positional arguments:
op1 op1 is xxx
op2 op2 is yyy
options:
-h, --help show this help message and exit
可选参数
我们可以为脚本添加可选参数(必须以-
或--
开头),例如
1
2
3
4
5
6import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--config", help="set config file")
args = parser.parse_args()
if args.config:
print("config is", args.config)
注意这里我们仍然通过args.config
获取对应的值。
使用例如 1
python test.py --config abc
我们也可以不提供可选参数 1
python test.py
但是如果我们使用了--config
,却在后面不提供值,就会报错
1
2usage: test.py [-h] [--config CONFIG]
test.py: error: argument --config: expected one argument
对于可选参数,我们可以选择支持长参数或短参数形式,或者同时使用两者,例如
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-c", "--config", help="set config file")
parser.add_argument("-v", help="set value")
parser.add_argument("--file", help="set file")
args = parser.parse_args()
if args.config:
print("config is", args.config)
if args.v:
print("value is", args.v)
if args.file:
print("file is", args.file)
如果同时支持长参数和短参数,需要通过长参数形式来获取选项的结果。
开关参数
前面的可选参数在提供选项时必须要提供对应的值,但有时候我们只关注有没有这个参数选项,起到开关作用,
可以使用action="store_true"
实现:
- 如果提供了选项,对应的值自动设置为
true
- 如果没有提供选项,对应的值自动设置为
false
与之相反的是action="store_false"
,解析器并不会将选项后面的内容视作选项的值。
1 | import argparse |
使用例如 1
python test.py --verbose
更多细节
丰富帮助信息
我们可以在定义解析器时,传入程序名称和描述信息,它们会显示在帮助信息中
1
2
3
4parser = argparse.ArgumentParser(
prog='ProgramName',
description='What the program does',
epilog='Text at the bottom of help')
其中prog
缺省时会自动使用脚本名称(会自动移除路径部分),description
是对程序的描述,epilog
是帮助信息最后的结束语,两者默认为空。
通常情况下,解析器会根据选项要求自动生成使用示例,我们也可以通过usage
参数指定
1
parser = argparse.ArgumentParser(prog='PROG', usage='%(prog)s [options]')
参数类型限制
例如 1
2
3
4
5
6import 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**2)
可选参数默认值
例如 1
2
3
4
5
6import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--config", default="config.ini", help="set config file")
args = parser.parse_args()
if args.config:
print("config is", args.config)
必需参数
例如 1
2
3
4
5
6import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--config", required=True, help="set config file")
args = parser.parse_args()
if args.config:
print("config is", args.config)
注意必需的优先级比默认值更高,如果设置为必需,那么提供的默认值实际上不起作用。
参数重复计数
我们可以支持重复某个选项多次,例如-v
和-vv
,后者将提供更详细的信息。
例如 1
2
3
4
5
6
7
8
9
10import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
"-v", "--verbosity", action="count", help="increase output verbosity"
)
args = parser.parse_args()
if args.verbosity:
print("verbosity turned on: {}".format(args.verbosity))
这里action="count"
代表对选项出现次数计数。
注意:如果不对这个选项设置default=0
,那么默认值会是None
。
使用例如 1
2
3
4
5
6
7
8
9
10
11python test.py -v
# verbosity turned on: 1
python test.py -vvvv
# verbosity turned on: 4
python test.py -vvvv --verbosity
# verbosity turned on: 5
python test.py -vvvv --verbosity --verbosity
# verbosity turned on: 6
参数合法范围
例如 1
2
3
4
5
6
7
8
9import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--value", type=int, choices=[0, 1, 2],
help="value")
args = parser.parse_args()
if args.value:
print("value: {}".format(args.value))