作者:HelloGitHub-ProdesireHelloGitHub的《讲解开源项目》系列,项目地址:https://github.com/HelloGitHu...前言为第一篇《探索》argparse》一文中,我们初步掌握了使用argparse的四个步骤,对它有了一个基本的认识。但是它具体支持什么类型的论证呢?这些参数应该如何配置?本文将带你深入了解argparse的参数。本系列文章默认使用Python3作为解释器。如果你还在使用Python2,请注意两者在语法和库使用上的差异~你还记得参数action吗?前四部分中的第二步是定义参数。在这一步中,我们指定动作输入参数:parser.add_argument('--sum',dest='accumulate',action='store_const',const=sum,default=max,help='sumthenums(default:findthemax)')那么这里的action,也就是参数action,是做什么用的呢?想象一下,当我们在命令行中输入一串参数时,我们想要针对不同类型的参数做不同的处理。那么参数action其实就是告诉解析器我们希望如何处理对应的参数。例如,参数值应该存储为一个值,还是附加到一个列表中?作为布尔值应该为True还是False?参数动作分为以下8类:store——保存参数的值,默认参数动作。它通常用于为参数指定一个值,例如指定一个名称:>>>parser.add_argument('--name')>>>parser.parse_args(['--name','Eric'])Namespace(name='Eric')store_const–存储一个常量命名的固定值。当我们想通过是否给一个参数来起到标志的作用,并且在给定的时候取一定的值,我们可以使用参数action,比如:>>>parser.add_argument('--sum',action='store_const',const=sum)>>>parser.parse_args(['--sum'])Namespace(sum=)>>>parser.parse_args([])Namespace(sum=None)store_true和store_false——是store_const的特例,分别用来存储True和False。如果是指定参数,则其默认值分别为False和True,如:>>>parser.add_argument('--use',action='store_true')>>>parser.add_argument('--nouse',action='store_false')>>>parser.parse_args(['--use','--nouse'])Namespace(nouse=False,use=True)>>>parser.parse_args([])Namespace(nouse=True,use=False)append——将参数值追加到列表中。它经常用在命令行上以允许多个相同的选项,例如:>>>parser.add_argument('--file',action='append')>>>parser.parse_args(['--file','f1','--file','f2'])Namespace(file=['f1','f2'])append_const-将const命名的固定值附加到列表(const的默认值为None)。常用于将多个参数对应的固定值保存在同一个list中,相应的需要配合dest入参放在同一个list中。例如:如果不指定dest入参,则将固定值保存在一个以参数名命名的变量中>>>parser.add_argument('--int',action='append_const',const=int)>>>parser.add_argument('--str',action='append_const',const=str)>>>parser.parse_args(['--int','--str'])Namespace(int=[],str=[])指定dest入参,固定值保存在dest命名的变量中>>>parser.add_argument('--int',dest='types',action='append_const',const=int)>>>parser.add_argument('--str',dest='types',action='append_const',const=str)>>>parser.parse_args(['--int','--str'])Namespace(types=[,])count——统计参数出现的次数,如:>>>parser.add_argument('--increase','-i',action='count')>>>parser.parse_args(['--increas','--increase'])Namespace(increase=2)>>>parser.parse_args(['-iii'])Namespace(increase=3)help——打印parser所有的完整帮助信息中的选项和参数,然后退出。version——打印命令行版本,通过指定version入参来指定版本,调用后退出。如:>>>parser=argparse.ArgumentParser(prog='CMD')>>>parser.add_argument('--version',action='version',version='%(prog)s1.0')>>>parser.parse_args(['--version'])CMD1.0parametercategory如果参数action定义了parser收到参数后如何处理参数,那么parsercategory就是告诉parser这个参数的meta信息,即是,参数看起来像什么。例如,如果参数是一个字符串怎么办?还是布尔类型?参数可选的值有多少?仍然可以给定值等。下面,我们将对不同类型的参数一一进行介绍。可选参数可选参数顾名思义,参数可以加,也可以不加。通过ArgumentParser.add_argument添加的参数默认是可选的。我们可以使用-来指定短参数,即短名称的参数;我们也可以用--来指定长参数,即名字很长的参数。当然,您也可以同时指定两者。通常使用可选参数:用户提供一个参数和对应的值,该值被使用;如果未提供,则使用默认值。如:>>>parser.add_argument('--name','-n')>>>parser.parse_args(['--name','Eric'])#通过长参数指定名字Namespace(name='Eric')>>>parser.parse_args(['-n','Eric'])#通过短参数指定名称Namespace(name='Eric')>>>parser.parse_args([])#不指定则默认参数类型为NoneNamespace(name=None)参数类型为parser要解析的参数值的类型,默认为str类型。我们可以通过输入类型参数来指定参数类型。argparse支持多种参数类型,可以是int、float、bool等,例如:>>>parser.add_argument('-i',type=int)>>>parser.add_argument('-f',type=float)>>>parser.add_argument('-b',type=bool)>>>parser.parse_args(['-i','1','-f','2.1','-b','0'])Namespace(b=False,f=2.1,i=1)此外,类型输入参数还可以是可调用对象。这给了我们很大的想象空间。我们可以指定type=open将参数值作为文件处理,也可以指定自定义函数进行类型检查和类型转换。作为文件处理:>>>parser.add_argument('--file',type=open)>>>parser.parse_args(['--file','README.md'])Namespace(b=None,f=None,file=<_io.TextIOWrappername='README.md'mode='r'encoding='cp936'>,i=None)使用自定义函数进行处理,入参为参数值,转换后值需要返回结果。比如参数--num,我们希望它的值小于1时返回1,大于10时返回10:>>>deflimit(string):...num=int(string)...如果num<1:...返回1...如果num>10:...返回10...返回num...>>>parser.add_argument('--num',type=limit)>>>parser.parse_args(['--num','-1'])#num小于1,则取1Namespace(num=1)>>>parser.parse_args(['--num','15'])#num如果大于10,取10Namespace(num=10)>>>parser.parse_args(['--num','5'])#如果num在1到10之间,取原值Namespace(num=5)参数默认值参数默认值用于命令行不传参数值时的默认值,默认指定即可。如果未指定此值,则参数默认为None。例如:>>>parser.add_argument('-i',default=0,type=int)>>>parser.add_argument('-f',default=3.14,type=float)>>>parser.add_argument('-b',default=True,type=bool)>>>parser.parse_args([])Namespace(b=True,f=3.14,i=0)位置参数位置参数按位置传递,而不是-或--以参数开头来指定参数值。例如,我们可以指定两个位置参数x和y,先添加的x在第一个位置,后添加的y在第二个位置。然后在命令行输入1和2,分别对应x和y:>>>parser.add_argument('x')>>>parser.add_argument('y')>>>parser.parse_args(['1','2'])Namespace(x='1',y='2')可选值可选值是受限参数值的内容,由choices入参指定。在某些情况下,我们可能需要限制用户输入参数的内容,只能在几个预设值中选择一个,那么可选值就派上用场了。例如指定文件读取模式限制为只读和读写:>>>parser.add_argument('--mode',choices=('read-only','read-write'))>>>parser.parse_args(['--mode','read-only'])Namespace(mode='read-only')>>>parser.parse_args(['--mode','read'])用法:[-h][--mode{read-only,read-write}]:error:argument--mode:invalidchoice:'read'(choosefrom'read-only','read-write')互斥参数aremutuallyexclusiveParameters是多个相互排斥的参数,不能同时出现。要使用互斥参数,首先要通过ArgumentParser.add_mutually_exclusive_group给解析器添加一个互斥组,然后将参数添加到这个组中,那么这个组中的所有参数都是互斥的。比如我们想通过命令行告知我们乘坐的车辆是小汽车、公交车还是自行车,那么我们可以这样写:>>>group=parser.add_mutually_exclusive_group()>>>group.add_argument('--car',action='store_true')>>>group.add_argument('--bus',action='store_true')>>>group.add_argument('--bike',action='store_true')>>>parser.parse_args([])#什么都不带bike=False,bus=True,car=False)>>>parser.parse_args(['--bike'])#骑行命名空间(bike=True,bus=False,car=False)>>>parser.parse_args(['--bike','--car'])#如果你想骑自行车和骑汽车,那是不可接受的用法:[-h][--car|--总线|--bike]:error:argument--car:notallowedwithargument--bikevariableparameterlist可变参数列表用来定义一个参数可以有多个值,值的个数可以通过nargs定义.如果nargs=N,N为数字,则要求参数提供N个值,如:>>>parser.add_argument('--foo',nargs=2)>>>print(parser.parse_args(['--foo','a','b']))Namespace(foo=['a','b'])>>>print(parser.parse_args(['--foo','a','b','c']))usage:[-h][--fooFOOFOO]:error:unrecognizedarguments:c如果nargs=?,则需要为参数提供0或1的值,如:>>>解析器.add_argument('--foo',nargs='?')>>>parser.parse_args(['--foo'])命名空间(foo=None)>>>parser.parse_args(['--foo','a'])命名空间(foo='a')>>>解析器。parse_args(['--foo','a','b'])usage:[-h][--foo[FOO]]:error:unrecognizedarguments:b如果nargs=*,参数需要提供0或更多值,例如:>>>parser.add_argument('--foo',nargs='*')>>>parser.parse_args(['--foo'])Namespace(foo=[])>>>解析器。parse_args(['--foo','a'])命名空间(foo=['a'])>>>解析器。parse_args(['--foo','a','b','c','d','e'])命名空间(foo=['a','b','c','d','e'])如果nargs=?,则要求至少为参数提供一个值,如:>>>par系列add_argument('--foo',nargs='+')>>>解析器。parse_args(['--foo','a'])命名空间(foo=['a'])>>>解析器。parse_args(['--foo'])usage:[-h][--fooFOO[FOO...]]:error:argument--foo:expectedatleastanargumentinthesectiontounderstandtheparameteraction和parametercategory之后,你是不是渐渐开始对使用argparse有了信心?至少,用目前学到的知识完成一个简单的命令行工具已经不是问题了。下一篇文章,让我们继续深入了解argparse的功能,如何修改参数前缀,如何定义参数组,以及如何定义嵌套解析器,如何编写自定义动作等等,让我们拭目以待~欢迎关注HelloGitHub公众号获取更多开源项目的资讯和内容。不再恐惧,让开源项目的发起者不再孤单。关注我们的文章,您将发现编程的乐趣,使用并发现参与开源项目是多么容易。欢迎联系我们投稿,让更多的人爱上开源,为开源做贡献~