Python argparse模块详解
argparse 是一个用来解析命令行参数的 Python 库,它是 Python 标准库的一部分。基于 python 2.7 的 stdlib 代码。argparse 模块使编写用户友好的命令行界面变得容易。程序定义了所需的参数,而 argparse 将找出如何从 sys.argv 中解析这些参数。argparse 模块还会自动生成帮助和使用消息,并在用户为程序提供无效参数时发出错误。
简单实现圆柱体体积的计算
为了便于对argparse命令行参数解析模块的理解,我们先从一个简单的程序入手:
import math
def cylinder_volume(radius, height):
vol = (math.pi) * (radius ** 2) * height
return vol
if __name__ == '__main__':
print(cylinder_volume(2, 4))
通过PyCharm执行代码,其显示的结果:
通过命令行的方式执行代码,其显示的结果:
可以看到如果使用命令行方式,需要先进入将要执行的xxx.py文件所在的文件目录下,并输入python xxx.py即可。
使用argparse模块实现圆柱体体积的计算
-
导入argparse模块
import argparse
-
创建一个解析对象parser
parser = argparse.ArgumentParser(description='Calculate volume of a Cylinder')
其中,parser解析对象相当于一个用来装载参数的容器,而description用来描述解析对象。
-
添加命令行参数
parser.add_argument('radius', type=int, help='Radius of Cylinder') parser.add_argument('height', type=int, help='Height of Cylinder') args = parser.parse_args()
在计算圆柱体体积的例子中,需要的参数由两个分别是radius和height,所以需要向解析对象中添加这两个参数,参数的类型定义为int类型,其中help用来对参数进行描述说明。
-
将原函数实参换成命令行参数
print(cylinder_volume(args.radius, args.height))
-
完整代码复现
import math import argparse parser = argparse.ArgumentParser(description='Calculate volume of a Cylinder') parser.add_argument('radius', type=int, help='Radius of Cylinder') parser.add_argument('height', type=int, help='Height of Cylinder') args = parser.parse_args() def cylinder_volume(radius, height): vol = (math.pi) * (radius ** 2) * height return vol if __name__ == '__main__': print(cylinder_volume(args.radius, args.height))
-
执行代码
在PyCharm中直接执行代码,其结果显示:
PyCharm会直接报错,因为这段代码需要传入参数。
现在通过命令行的方式执行代码,其结果显示:
可以看见结果与之前的是一样的。
接着,我们可以调用–help或-h参数来查看程序的描述:
现在,我们尝试将先前传入的参数顺序进行改变,得到的结果如下:
可以看见结果就完全不一样了,从help中的提示信息知道,传入的参数需要按照严格的顺序进行,然而,在日常中,可能涉及到的参数数目较多,对于参数的顺序不是那么好记忆,这时我们可以对原先的代码进行修改,使其能使用选择性参数来进行:
parser.add_argument('-r', '--radius', type=int, help='Radius of Cylinder')
parser.add_argument('-H', '--height', type=int, help='Height of Cylinder')
这里需要注意,由于 ‘-h’ 参数已经被help命令占用,所以对于height,我们使用 ’-H‘ 。
下面是再次执行代码的显示结果:
现在,我们通过 ’-h‘ 来查看程序的描述:
如果想让上面的描述看起来比较简洁,可以将代码进行修改:
parser.add_argument('-r', '--radius', type=int, metavar='', help='Radius of Cylinder')
parser.add_argument('-H', '--height', type=int, metavar='', help='Height of Cylinder')
现在,我们再次通过 ’-h‘ 来查看效果:
那现在如果只输入一个参数,结果会怎样呢?
可以看到报错信息中,那个没有具体指定数值的参数会被赋予None值,为了避免这种情况,我们可以对代码进行如下修改:
parser.add_argument('-r', '--radius', type=int, metavar='', required=True, help='Radius of Cylinder')
parser.add_argument('-H', '--height', type=int, metavar='', required=True, help='Height of Cylinder')
现在再来执行一次:
可以看到此时会提示需要添加的参数。
互斥参数的介绍
现在我们尝试添加互斥组:
group = parser.add_mutually_exclusive_group()
group.add_argument('-q', '--quiet', action='store_true', help='print quiet')
group.add_argument('-v', '--verbose', action='store_true', help='print verbose')
首先建立一个group容器,接着向其中添加参数,action参数赋值为’store_true‘意味着当在命令中添加’-q‘或者’–quiet‘(’-v‘或者’–verbose‘)时,程序将对args.quiet赋值为true,而默认情况下为false。接着利用这一原理,我们就可以对main函数的内容进行修改:
volume = cylinder_volume(args.radius, args.height)
if args.quiet:
print("quiet: %s" % volume)
elif args.verbose:
print("verbose: %s" % volume)
else:
print("Volume of a Cylinder with radius %s and height %s is %s" % (args.radius, args.height, volume))
现在进行命令行测试,查看效果:
需要注意的是,互斥的含义是指不能同时参入互斥组中的参数,即只有一个参数能成立,如果强行传入互斥组中两个以上的参数,则会出现如下错误提示:
完整版改进代码
import math
import argparse
parser = argparse.ArgumentParser(description='Calculate volume of a Cylinder')
parser.add_argument('-r', '--radius', type=int, metavar='', required=True, help='Radius of Cylinder')
parser.add_argument('-H', '--height', type=int, metavar='', required=True, help='Height of Cylinder')
group = parser.add_mutually_exclusive_group()
group.add_argument('-q', '--quiet', action='store_true', help='print quiet')
group.add_argument('-v', '--verbose', action='store_true', help='print verbose')
args = parser.parse_args()
def cylinder_volume(radius, height):
vol = (math.pi) * (radius ** 2) * height
return vol
if __name__ == '__main__':
volume = cylinder_volume(args.radius, args.height)
if args.quiet:
print("quiet: %s" % volume)
elif args.verbose:
print("verbose: %s" % volume)
else:
print("Volume of a Cylinder with radius %s and height %s is %s" % (args.radius, args.height, volume))