Python -- argparse(命令行与参数解析)
Python – argparse(命令行与参数解析)
Persus & Xie
在我们用脚本去处理特定的任务时,有时候需要提供一些参数,而参数又是不确定且可变的,这时我们一般会选择通过在terminal命令行中加入参数进而传递参数,根据所传递的参数进行处理。
sys.argv
在Python中,命令行的参数和C语言很类似。C语言中,main函数的原型为int main(int argc, char **argv),这里主要指linux或者MACOS平台,argc指的是命令行传递的参数个数(程序的name为第一个参数),而argv则是一个指针数组,每一个元素为指向一个命令行参数的指针。在Python里,命令行参数储存在sys.argv中,argv是一个列表,第一个元素也为程序名称。
sys.argv 实例
我们通过实例1.1理解sys.argv的运行过程。
实例1.1
,创建脚本argv.py:
#!/usr/bin/python
#example 1.1
import sys
ar1 = sys.argv[0]
ar2 = sys.argv[1]
ar3 = sys.argv[1:]
ar4 = sys.argv[2:]
print(ar1)
print(ar2)
print(ar3)
print(ar4)
在terminal中运行命令:
python argv.py p e r s u s
运行结果:
argv.py
p
['p', 'e', 'r', 's', 'u', 's']
['e', 'r', 's', 'u', 's']
在terminal中运行命令:
python argv.py persus
运行结果:
argv.py
persus
['persus']
[]
通过以上实例我们可以看出,sys将参数以列表的形式存储,列表中第一个元素为所运行程序的名字,在命令行中,各个参数以空格隔开,列表中元素类型为字符型。
但是,sys.argv需要用很多逻辑处理传入的参数,来判别各种情形,比如:传入的参数多了还是少了、是不是有效参数、等等。这些逻辑处理需要分析各种可能的情况,并将逻辑处理写入程序,在一定程度上会浪费时间精力。
argparse库,则可以帮助省去这些逻辑处理部分。
argparse 模块
argparse是Python的一个库,用于为程序提供命令行接口(Command Line Interface)。使用这个库主要由4步来完成:
- import argparse
- 创建 parser
- 向parse添加位置变量和可选变量
- 运行 parser.parse_args()
注意,每一步都是必需的,例如,如果只创建了parser,而缺少后面两步,在运行help时将不会打印帮助文档。
在执行parser.parse_args()后,会得到一个Namespace object,里面包含了从命令行中传入的参数信息。
命令行接口支持两种类型的参量:
- Positional arguments 位置参量
- Optional arguments 可选参量
位置参量是用户必须设置的参量,例如 cd
命令后的path
参数,不设置就没办法运行,它之所以叫位置参量,是因为它们在命令中传入的位置不能错,必须按照代码中加入parser
的先后顺序传入。
可选参量对于代码运行不是必须的,但是设置后可以改变程序的行为,例如对 cp
命令,-r
就是可选变量,设置后可以迭代地复制整个文件夹。 在parser.add_argument()
时,可选变量必须有一条或两条短线 -
作为前缀,而位置变量则没有。一般把一条短线跟一个字母作为可选变量的缩写,方便命令行传入参数。
实例1.2
在此目录下有两个文件 argv.py,argv2.py。argv2.py内容如下所示:
#!/usr/bin/python
#example 1.2
import argparse #1)导入模块
import sys
import os
parser = argparse.ArgumentParser(description='List the content of a folder') # 2)创建parser
parser.add_argument('Path', metavar='path', type=str, help='the path to list') # 3)向parse添加位置变量和可选变量
args = parser.parse_args() # 4)运行 parser.parse_args(),获得Namespace object
input_path = args.Path
# 判断传入的路径参数
if not os.path.isdir(input_path):
print('The path specified does not exist')
sys.exit()
print('\n'.join(os.listdir(input_path)))
在terminal中运行命令:
python argv2.py
运行结果:
usage: argv2.py [-h] path
argv2.py: error: the following arguments are required: path
在terminal中运行命令:
python argv2.py ./
运行结果:
argv.py
argv2.py
在terminal中运行命令:
python argv2.py ./ps
运行结果:
The path specified does not exist
以上三条命令分别表示:不传入位置参数、传入正确的位置参数以及传入错误的位置参数。
可以发现,不用在代码中写入判别语句,argparse模块可以自动检测出调用时没有传入制定的path参数并准确报错。同时在usage行,还提示:可以选择提供 -h
参数查看帮助。
在terminal中运行命令:
python argv2.py -h
运行结果:
usage: argv2.py [-h] path
List the content of a folder
positional arguments:
path the path to list
optional arguments:
-h, --help show this help message and exit
打印出的帮助信息包含了该函数的调用方法,函数的用途,位置参数(必须设置的)、可选的变量等等。
设置程序的名字
默认情况下,argparse
函数库把sys.argv[0]
,即当前被执行代码的文件名设置为程序的名字,其主要用在help文档中,但是用户也可以在创建parser时,通过设置prog
参数自定义程序名。把实例1.2中第6行代码修改如下:
parser = argparse.ArgumentParser(prog='Perseus',
description='List the content of a folder')
在terminal中运行命令:
python argv2.py
运行结果:
usage: Perseus [-h] path
Perseus: error: the following arguments are required: path
可以发现,程序的名字由原来默认的argv2.py
被修改成了Perseus
设置 Usage Help
上文中,通过运行python argv2.py -h
可以查看代码的帮助文档,文档的第一行即展示了代码的调用方法:usage: argv2.py [-h] path
,或者是我们自定义的程序名:usage: Perseus [-h] path
. 我们也可以通过设置自定义这一行展示的内容。再次修改实例1.2中第6行代码如下:
parser = argparse.ArgumentParser(prog='Perseus',
usage='%(prog)s [options] path Displays the file under the specified path ',
description='List the content of a folder')
在terminal中运行命令:
python argv2.py -h
运行结果:
usage: Perseus [options] path Displays the file under the specified path
List the content of a folder
positional arguments:
path the path to list
optional arguments:
-h, --help show this help message and exit
设置help中开头和末尾的文字
通过定义description
和epilog
可以自定义帮组文档开头和末尾部分的文字。修改实例1.2中的第6行:
parser = argparse.ArgumentParser(prog='Perseus',
usage='%(prog)s [options] path Displays the file under the specified path ',
description='List the content of a folder',
epilog='Have a fun with the software')
运行结果:
usage: Perseus [options] path Displays the file under the specified path
List the content of a folder <<<<<<<<<<<< 改动处
positional arguments:
path the path to list
optional arguments:
-h, --help show this help message and exit
Have a fun with the software <<<<<<<<<<<<<改动处
自定义前缀字符
在默认情况下,命令行输入代码时,传入的可选变量(optional arguments)要用短线 -
作为前缀字符(prefix chars)。这个前缀字符可以通过设置prefix_chars
来定义。只是这个功能很少被用到,习惯性用法依旧是短线-
。继续修改实例1.2的第6行:
parser = argparse.ArgumentParser(prog='Perseus',
usage='%(prog)s [options] path Displays the file under the specified path ',
description='List the content of a folder',
epilog='Have a fun with the software',
prefix_chars='+')
在运行命令时就需要更改为:
python argv2.py +h
运行结果为:
usage: Perseus [options] path Displays the file under the specified path
List the content of a folder
positional arguments:
path the path to list
optional arguments:
+h, ++help show this help message and exit <<<<<<<<<<<< Here
Have a fun with the software
添加参量
当程序需要传递多个参量时,我们通常会为参量设置标示,例如:
python example.py -n1 para1 -n2 para2
此命令中,para1
为参量名n1
传入的参数,para2
为参量名n2
传入的参数。当然,我们需要在程序中添加关于参量n1,n2
的命令,即运用实例第7行的语句,parser.argument()
函数。下文将通过实例详细描述parser.argument()
函数。
实例1.3
创建一个命令行输入参数的计算器程序argv3.py,该程序可以对传的两个数据进行加减乘除运算。程序内容如下:
#!/usr/bin/python
#example 1.3
import argparse #1)导入模块
import sys
import os
parser = argparse.ArgumentParser(prog='Calculate',
usage='%(prog)s [options] calculate two numbers',
description='This is a calculate program') # 2)创建parser
parser.add_argument('-n1', '--value1', type=float, help='the first Number input ') # 3)向parse添加参数1,第二个数值
parser.add_argument('-n2', '--value2', type=float, help='the first Number input ') # 3)向parse添加参数2,第一个数值
parser.add_argument('-ope', '--operator',default='+', help='the Calculation of operator,+,-,*,/') # 3)向parse添加参数3,运算符号
args = parser.parse_args() # 4)运行 parser.parse_args(),获得Namespace object
print(args)
result = None
ope = args.operator
num1 = args.value1
num2 = args.value2
if ope == '+':
result = num1 + num2
elif ope == '-':
result = num1 - num2
elif ope == '*':
result = num1 * num2
elif ope == '/':
if num2 !=0:
result = num1/num2
else:
print('the num2 cannot be equal to 0')
else:
print("More algorithms please wait for updates")
print("Result:",result)
程序中,添加参数时,我们可以对参数设置默认值,default=
。对参量值的类型设置是通过在parser.add_argument()
设置type
来确定的。如实例1.3第9行。
其中程序中对参数变量的读取索引是双横杠后的字符,如--value1
,读取参数n1
时,只需读取args.value1
即可。
这里涉及用两个短线引导的可选变量(optional argument),它和不用短线引导的位置变量(positional argument)的区别是,在命令行传入该变量时,需要显示指定变量名,而使用两个短线引导的可选变量时,可以只输入变量的前几个字符,不需要完整输入名称。
但是对于我们所设置的--value1
和--value2
无法对变量名进行缩减,如缩减为--val
时,两个参量会混淆。
假如希望关闭可缩减变量名,可以在初始化parser
时设置,allow_abbrev=False
,即:
parser = argparse.ArgumentParser(prog='Calculate',
allow_abbrev=False,
usage='%(prog)s [options] calculate two numbers',
description='This is a calculate program')
在terminal中运行命令:
python_t % python argv3.py -h
运行结果:
usage: Calculate [options] calculate two numbers
This is a calculate program
optional arguments:
-h, --help show this help message and exit
-n1 VALUE1, --value1 VALUE1
the first Number input
-n2 VALUE2, --value2 VALUE2
the first Number input
-ope OPERATOR, --operator OPERATOR
the Calculation of operator,+,-,*,/
在terminal中运行命令:
python argv3.py -n1 5 -n2 6 -ope -
运行结果:
Namespace(operator='-', value1=5.0, value2=6.0)
Result: -1.0
在terminal中运行命令:
python argv3.py -n1 5 -n2 6 --o +
运行结果:
Namespace(operator='+', value1=5.0, value2=6.0)
Result: 11.0
设置每个参量在命令行读入值的数目
parser默认情况下,会给每个命令行的参量量分配它后面相邻的值,但是也可以在程序增加参量parser.add_argument()
时,通过设置nargs
来让这个变量读入更多的值,例如:
实例1.4
创建argv4.py,程序内容为:
#!/usr/bin/python
#example 1.4
import argparse
parser = argparse.ArgumentParser(prog='Perseus',
usage='%(prog)s [options] the usage of nargs',
description='This is a test program')
parser.add_argument('--inumber',type=float,nargs=3)
args = parser.parse_args()
print(args.inumber)
设置nargs=3
后,该参量会强制从命令行读入3个值,假如给定的数目不够或者数目过多,就会报错,比如:
在terminal中运行命令:
python argv4.py --inumber 6
运行结果:
usage: Perseus [options] the usage of nargs
Perseus: error: argument --inumber: expected 3 arguments
在terminal中运行命令:
python argv4.py --inumber 6 6 6
运行结果:
[6.0, 6.0, 6.0]
在某些情况下,我们某些参量的值的个数不一定是固定的,比如在模拟程序中,我们有时候需要选择不同的分布模型,比如指数分布、正态分布、gamma分布等等,对于不同分布模型,其参数个数是不同的,nargs
也提供了不同的选项,?, *, +
,其中:
?
: 读取一个值,可以不设置,默认情况是 nargs = ‘?’
*
: 读多个值(包括0个),会被收集到一个列表中
+
: 读取至少一个值
将实例1.4
第7行更改为:
parser.add_argument('--inumber',type=float,nargs='*')
在terminal中运行命令:
python argv4.py --inumber 6 6 6
运行结果:
[6.0, 6.0, 6.0]
在terminal中运行命令:
python argv4.py --inumber 6 6
运行结果:
[6.0, 6.0]
设制变量为限定范围的选择
实例1.5
:创建脚本argv5.py,内容为:
#!/usr/bin/python
#example 1.5
import argparse
parser = argparse.ArgumentParser(prog='Perseus',
usage='%(prog)s [options] the usage of nargs',
description='This is a test program')
parser.add_argument('--ch',choices=['perseus','crux'],required=True,
help='you must input a chice foarm [perseus,crux]')
args = parser.parse_args()
print(args.ch)
在terminal中运行命令:
python argv5.py -h
运行结果:
usage: Perseus [options] the usage of nargs
This is a test program
optional arguments:
-h, --help show this help message and exit
--ch {perseus,crux} you must input a chice foarm [perseus,crux]
在terminal中运行命令:
python argv5.py --ch local
运行结果:
usage: Perseus [options] the usage of nargs
Perseus: error: argument --ch: invalid choice: 'local' (choose from 'perseus', 'crux')
在terminal中运行命令:
python argv5.py --ch perseus
运行结果:
perseus
设置参量的action参数
对于可选参量,可以设置它的action
参数。这个参数可以设置为如下项:
store
将输入的值保存在Namespace
实例中。这个是默认设置,即action='store'
store_const
当选择此项时,保存为一个常数,但是后面需要加const
指定,否则会报错
store_true
当选择此项时,会给它绑定一个布尔值True
,显示设定后绑定False
store_false
当选择该项时,不设置绑定的是True
,显式设定后绑定False
append
保存一个列表,每次设置这个变量,都会为列表添加一个值。
append_const
每次设置时给列表添加一个常量
count
保存一个整数,整数的值为该参量被设置的次数
help
显示帮助文档并退出
version
显示程序版本并退出
实例1.6
创建脚本argv6.py,内容如下:
#!/usr/bin/python
#example 1.6
import argparse
parser = argparse.ArgumentParser(prog='Perseus',
usage='%(prog)s [options] the usage of action',
description='This is a test program')
parser.version = '1.6'
parser.add_argument('-a', action='store')
parser.add_argument('-b', action='store_const', const=12)
parser.add_argument('-c', action='store_true')
parser.add_argument('-d', action='store_false')
parser.add_argument('-e', action='append')
parser.add_argument('-f', action='append_const', const=10)
parser.add_argument('-g', action='count')
parser.add_argument('-i', action='help')
parser.add_argument('-j', action='version')
args = parser.parse_args()
print(vars(args))
该代码将每种action
分配给指定的可选参量,然后打印出它们从命令行所捕获的值。
首先,我们调用时不显示设置任何参量,以观察它们的默认值:
在terminal中运行命令:
python argv6.py
运行结果:
{'a': None, 'b': None, 'c': False, 'd': True, 'e': None, 'f': None, 'g': None}
可以发现,大多数参量的默认值均为None
,除了绑定了store_true
和store_false
的变量,不在命令行显式设置它们时,它们默认存储的是和action
相反的False
和True
。
对于设定action=store
的参量,它会直接存储命令行传入的参数而不做任何修改。
在terminal中运行命令:
python argv6.py -a 6 -b -c -d -e perseus -e crux -e local -f -f -ggggg
运行结果:
{'a': '6', 'b': 12, 'c': True, 'd': False, 'e': ['perseus', 'crux', 'local'], 'f': [10, 10], 'g': 5}
设置可选参量为必选项
有时必须为程序设定参量的具体值,就需要将可选参量设为必选项,设施方法为在parser.add_argument()
中增加 required=True
,示例如下,required
参数只能绑定给 optional argument 上,因此 -ch
前面的短线是必要的。此外,设置了 required
后 default
将不起作用。
parser.add_argument('-ch',
action='store',
choices=['persus', 'crux'],
required=True)
定义互斥的参量
互斥参量,即两个参量只能在命令行中选一个进行设置,否则将会报错。示例如下:
实例1.7
创建argv7.py
#!/usr/bin/python
#example 1.7
import argparse
parser = argparse.ArgumentParser(prog='Perseus',
usage='%(prog)s [options] the usage of group',
description='This is a test program')
group = parser.add_mutually_exclusive_group(required=True) # 这一行创建互斥组
group.add_argument('-c', '--crux', action='store_true') # 在互斥组中加变量
group.add_argument('-p', '--perseus', action='store_true')
args = parser.parse_args()
print(vars(args))
在terminal中运行命令:
python argv7.py -c
运行结果:
{'crux': True, 'perseus': False}
在terminal中运行命令:
python argv7.py -c -p
运行结果:
usage: Perseus [options] the usage of group
Perseus: error: argument -p/--perseus: not allowed with argument -c/--crux
禁用 Auto Help
在上述中,我们经常用到传入-h
参量来获取argparse
自动生成的帮助文档,这个功能也是可以被禁止的,只需要在argparse.ArgumentParser()
加入add_help=False
总结
本文是在学习argparse
模块时所整理的内容,其基本上包括了我们在命令行传递参量时的需求。
本文参考文章为:
更多推荐
所有评论(0)