Python作为一种脚本语言,可以很方便的编写各种工具。当你想在服务器端运行一个工具或服务时,输入参数似乎是一个硬性要求(当然你也可以通过配置文件来实现)。如果你想在命令行上执行,那么你需要一个命令行参数解析模块来帮助你完成这项艰巨的工作。Python本身提供了三个命令行参数解析模块,这里我把它们的大概情况罗列一下,供大家了解。getopt只能简单处理命令行参数。optparse功能强大且简单易用,可以轻松生成符合Unix/Posix规范的标准命令行指令。(Python2.7后弃用,不再继续开发)argparse,更容易编写用户友好的命令行界面。它需要程序进程定义参数,argparse会更好的解析sys.argv。同时argparse模块还可以在用户输入错误参数时自动生成帮助和提示信息。很多初学者可能会用到getopt,简单好用,简单易用。比如optget不能解析一个有多个值的参数,比如--filefile1file2file3,而optparse我其实没有用过,但是考虑到Python2.7之后就不再维护了,所以我们一般不会用它.接下来就只剩下argparse了,几乎可以满足我对命令解析器的所有需求。支持解析一参数多值,自动生成帮助命令和帮助文档,支持分解析器,支持限制参数取值范围等。不管HelloWorld学什么,第一步应该是掌握它的大体框架。在使用argparse之前,框架很简单,只需要记住这三行即可。#mytest.pyimportargparseparser=argparse.ArgumentParser(description="usedfortest")args=parser.parse_args()现在试试[root@localhost~]#pythonmytest.py-husage:mytest.py[-h]usedfortestoptionalarguments:-h,--helpshowthishelpmessageandexit[root@localhost~]#[root@localhost~]#[root@localhost~]#pythonmytest.py[root@localhost~]#就可以使用了。1.入门配置这里说一下比较常用的参数配置。调试:调试版本号:versionimportargparseparser=argparse.ArgumentParser()parser.add_argument('--version','-v',action='version',version='%(prog)sversion:v0.01',help='showtheversion')parser.add_argument('--debug','-d',action='store_true',help='showtheversion',default=False)args=parser.parse_args()print("===end====)上面debug时的配置,需要说的是action='store_true'和default=Falsestore_true的作用和区别:一旦指定-d或--debug,其值为True,store_false为default=False的反义词:如果不指定-d或--debug,它的值默认为False,当我们执行pythonmytest.py-v时,会打印version中的内容。[root@localhost~]#pythonmytest.py-vmytest.pyversion:v0.01[root@localhost~]#执行一次,指定参数-v,执行parser.parse_args()后程序退出,不打印最后===结束===2。参数类型参数可分为强制参数(positionalarguments)和可选参数(optionalarguments)。如何在argsparse中实现它?requiredparameters使用words作为参数,默认是requiredparametername参数看一下:pythonmytest.py[root@localhost~]#pythonmytest.pyusage:mytest.py[-h]namemytest.py:error:toofewarguments[root@localhost~]#果然报错,说缺少参数。然后我们指定:pythonmytest.pynamewangbm[root@localhost~]#pythonmytest.pywangbmwangbm[root@localhost~]#可选参数有两种方式:单下划线-指定短参数,如-h;双下划线--指定长参数,例如--help#mytest.pyimportargparsparser=argparse.ArgumentParser()parser.add_argument("-v","--verbosity",help="increaseoutputverbosity")args=parser.parse_args()ifargs.verbosity:print("verbosityturnedon")else:print("verbosityturnedoff")运行pythonmytest.py没有错误。[root@localhost~]#pythonmytest.pyverbosityturnedoff[root@localhost~]#3。参数类型的参数有的是字符串,有的参数是值。为了有效地约束命令行中的参数,我们可以预先声明参数的类型。argparse会检查参数,如果检查失败,会直接抛出错误。#mytest.pyimportargparseparser=argparse.ArgumentParser()parser.add_argument("name")parser.add_argument("age",type=int)args=parser.parse_args()print(args.name)print(args.age)测试我们走吧。[root@localhost~]#pythonmytest.pywangbmeighteenusage:mytest.py[-h]nameagemytest.py:error:argumentage:invalidintvalue:'eighteen'[root@localhost~]#[root@localhost~]#pythonmytest.pywangbm18wangbm18[root@localhost~]#看,写18不行,提示类型不合法,只能写18。4互斥参数有些参数是互斥的,你没有我。例如,性别。这是如何在argparse中实现的?importargparseparser=argparse.ArgumentParser()group=parser.add_mutually_exclusive_group()group.add_argument("-m","--male",action="store_true")group.add_argument("-f","--female",action="store_true")args=parser.parse_args()如果同时指定这两个参数,会报错。[root@localhost~]#pythonmytest.py-f[root@localhost~]#pythonmytest.py-m[root@localhost~]#pythonmytest.py-m-fusage:mytest.py[-h][-m|-f]mytest.py:error:argument-f/--female:notallowedwithargument-m/--male[root@localhost~]#5如果可选值是gender,可以放在上面两个参数和then可以用互斥组约束,也可以放在一个参数里,在argparse里约束,然后在外层判断。#mytest.pyimportargparseparser=argparse.ArgumentParser()parser.add_argument("-g","--gender",default='male',choices=['male','female'])args=parser.parse_args()print(args.gender)尝试执行一下,发现性别只能是男或女,不能是人妖。[root@localhost~]#pythonmytest.py--gendermalemale[root@localhost~]#pythonmytest.py--genderfemalefemale[root@localhost~]#[root@localhost~]#[root@localhost~]#pythonmytest.py--genderotherusage:mytest.py[-h][-g{male,female}]mytest.py:error:argument-g/--gender:invalidchoice:'other'(choosefrom'male','female')[root@localhost~]#6。指定文件通常需要在脚本中指定配置文件或其他文件。您可以使用以下配置argparse.FileType('rb'))args=parser.parse_args()dest=files意思是将命令行中--file的参数值赋值给变量files,用args.files访问即可。action=append,因为我们需要指定多个文件,多次指定--file,argparse会把它放在一个列表中。type=argparse.FileType('rb'),因为是指定文件,参数应该是路径,指定打开方式为rb。如果想获取文件内容,可以使用args.files[0].read()7。子解析器如果您对命令行有足够的了解,您就会知道在某些情况下存在子解析器。这里我就以我在工作中遇到的一个例子来举例说明。cloud-init--debugsingle-namemymodule其中single后跟一个子解析器。#cloud-init.pydefmain_single(name,args):print("name:",name)print("args:",args)print("Iammain_single")#添加一个子解析器subparsers=parser.add_subparsers()parser_single=subparsers.add_parser('single',help='runasinglemodule')#给单个子解析器添加动作函数。parser_single.set_defaults(action=('single',main_single))#require=True:在命令行指定单个解析器,必须包含--name参数。parser_single.add_argument("--name",'-n',action="store",help="modulenametorun",required=True)args=parser.parse_args()(name,functor)=args.actionifnamein["single"]:functor(name,args)执行命令cloud-initsingle-namemymodule,输出如下,name='mymodule')Iammain_single以上是argparse的使用方法。
