开门见山,举一个简易计算器代码的例子,其中sys.argv用来读取脚本执行时后面传入的参数。python
def calculator(x, y, operation): if "add" == operation: return x + y elif "mod" == operation: return x % y elif "sub" == operation: return x - y elif "div" == operation: return x / y elif "mul" == operation: return x * y def main(): print(calculator(sys.argv[1], sys.argv[2], sys.argv[3])) if __name__ == '__main__': main()
咱们定义了一个calculator方法来完成一些简单的计算工做,这看来至关平凡,但对于用户来讲,在没有良好的文档支持的前提下,传入不一样参数有不一样的行为,若是只有少许参数还能够接受,随着参数的增长,方法会变得愈来愈不易使用。这时候便须要参数解析,argparse模块便官方推荐的在optparse基础上更进一步的改良版标准库。让咱们在了解一下她的庐山真面目以前先经过一个例子来了解argparse相关特性。api
相信小伙伴们都或多或少用过Linux系统,让咱们经过下面这个例子直观的了解argparse能作什么。bash
# 只输入ls,默认显示当前目录下内容 [root@host workarea]# ls pythondemo scripts # 当咱们给ls命令加一个参数,便会去找这个参数对应目录下的内容 [root@host workarea]# ls pythondemo/ arg1.py argparsedemo1.py fangzhen.py numpyapi.py tools # 咱们也可使用ls -[cmd]来改变行为,得到更详细的信息 [root@host workarea]# ls -l total 8 drwxr-xr-x 3 root root 4096 Dec 14 14:05 pythondemo drwxr-xr-x 2 root root 4096 Dec 14 14:29 scripts # 若是咱们想知道ls命令的其余用法和相关信息可使用ls --help [root@host workarea]# ls --help Usage: ls [OPTION]... [FILE]... List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuvSUX nor --sort is specified. Mandatory arguments to long options are mandatory for short options too. -a, --all do not ignore entries starting with . -A, --almost-all do not list implied . and .. ...
脚本传入后的参数显示的绑定,让用户更清楚本身在执行什么操做,而且给用户一些提示信息在他忘记如何使用咱们的脚本时,这即是咱们要作的,固然若是参数数量很少,或者行为不复杂能够不使用。app
#整体使用流程以下 import argparse # 模板建立一个解析参数对象 parser = argparse.ArgumentParser() # 用来指定程序须要接受的命令参数 parser.add_argument() # 经过分析指定的参数返回一些数据 args = parser.parse_args()
咱们直接试着用argparse对上面的例子进行改造,直观感觉下区别this
def calculator(args): operation = args.operation x = args.x y = args.y if "add" == operation: return x + y elif "mod" == operation: return x % y elif "sub" == operation: return x - y elif "div" == operation: return x / y elif "mul" == operation: return x * y def main(): parser = argparse.ArgumentParser() parser.add_argument("--x", type=float, default=1.0, help="What is the first number") parser.add_argument("--y", type=float, default=1.0, help="What is the second number") parser.add_argument("--operation", type=str, help="What operation? [add,mod,sub,div,mul]") args = parser.parse_args() print(args) print(calculator(args)) if __name__ == '__main__': main()
通过简单的改造,调用calculator方法时,咱们能够更清楚本身在作什么操做,而且能够根据帮助信息使用而不须要去阅读源码了,这真的节省了不少没必要要的时间。spa
# 直接调用不加参数,会提示None,命名空间那行为print(args) [root@host pythondemo]# python arg2.py Namespace(operation=None, x=1.0, y=1.0) None # 加上参数-h 或 --help咱们就能看到帮助信息,感受像模像样 [root@host pythondemo]# python arg2.py -h usage: arg2.py [-h] [--x X] [--y Y] [--operation OPERATION] optional arguments: -h, --help show this help message and exit --x X What is the first number --y Y What is the second number --operation OPERATION What operation? [add,mod,sub,div,mul] # 参数传入方法,这里的等于号能够省略 [root@host pythondemo]# python arg2.py --x=2 --y=3 --operation=mul 6.0 # 当咱们少输入或者没有输入要求的参数 [root@host pythondemo]# python arg2.py 2 usage: arg2.py [-h] [--x X] [--y Y] [--operation OPERATION] arg2.py: error: unrecognized arguments: 2
固然这并无完成咱们的所有需求,咱们还能够作的更好,那么咱们就得深刻了解下今天得主角argparse。命令行
咱们能够给解析模板来个简单得标题,会在--help中显示code
argparse.ArgumentParser(description='sample demo')
若是咱们不想用Linux风格的"-"或"--"来做为命令前缀,咱们自定义以下orm
parser = argparse.ArgumentParser(prefix_chars='-+/')
模板建立时是默认添加-h和--help帮助信息的,若是咱们不想要,写能够去除掉对象
argparse.ArgumentParser(add_help=False)
咱们也能够添加版本信息,会自动加入获取版本信息的-v和--version命令
argparse.ArgumentParser(version='1.0')
直接在方法里加一个字符串"-a"或"--a"当在脚本后面调用传入值后,均可以使用arg.a获取传入值,传入值默认从sys.argv【1:】中得到
parser.add_argument("-a") args = parser.parse_args() print(args) print(args.a) # 结果 λ python exam2.py --a=1 Namespace(a='1') 1
若是咱们想改变访问方式能够用dest参数
parser.add_argument("--a", dest="c") args = parser.parse_args() print(args) print(args.c) # 结果 λ python exam2.py --a=1 Namespace(c='1') 1
咱们也能够不用变量显示赋值的方式,不加“-”或“--”,这样传入值和参数定义的顺序同样,这种状况desk不奏效
parser.add_argument("a") parser.add_argument("b") args = parser.parse_args() print(args) # 结果 λ python exam2.py 1 2 Namespace(a='1', b='2')
固然咱们也能够给传入两种接受方式,这种状况"-"开头的为命令简写,获取传入参数用"--"后的属性
parser.add_argument('-n', '--name', help="What's ur name") args = parser.parse_args() print(args) print(args.name) # 结果 λ python exam3.py -n=ling Namespace(name='ling') ling λ python exam3.py --name=wang Namespace(name='wang') wang
默认咱们传入的值会看成字符串来处理,若是咱们须要指定类型可使用type参数,如上面计算器中定义所示,若是不指定type为int,便会报错。默认支持的type类型有 int,float,open
parser.add_argument(type="")
若是肯定动做须要传入参数的个数,咱们也能够加nargs作强制限制。["n":参数的绝对个数,"?":0或1个,"*":0或因此,"+":全部而且至少一个]
parser.add_argument(nargs="")
argparse内置6种动做能够在解析到一个参数时进行触发:
store
保存参数值,可能会先将参数值转换成另外一个数据类型。若没有显式指定动做,则默认为该动做。
store_const
保存的常量,若是触发此动做,值是参数规格中提早被定义的值,而不能命令行传入值。
store_ture
/store_false
保存相应的布尔值。这两个动做被用于实现布尔开关。
append
将值保存到一个列表中。若参数重复出现,则保存多个值。
append_const
将一个定义在参数规格中的值保存到一个列表中。
version
打印关于程序的版本信息,而后退出
用法以下所示:
parser.add_argument('-s', action='store', dest='simple_value', help='Store a simple value') parser.add_argument('-c', action='store_const', dest='constant_value', const='value-to-store', help='Store a constant value') parser.add_argument('-t', action='store_true', default=False, dest='boolean_switch', help='Set a switch to true') parser.add_argument('-f', action='store_false', default=False, dest='boolean_switch', help='Set a switch to false') parser.add_argument('-a', action='append', dest='collection', default=[], help='Add repeated values to a list') parser.add_argument('-A', action='append_const', dest='const_collection', const='value-1-to-append', default=[], help='Add different values to list') parser.add_argument('-B', action='append_const', dest='const_collection', const='value-2-to-append', help='Add different values to list') parser.add_argument('--version', action='version', version='%(prog)s 1.0') results = parser.parse_args() print 'simple_value =', results.simple_value print 'constant_value =', results.constant_value print 'boolean_switch =', results.boolean_switch print 'collection =', results.collection print 'const_collection =', results.const_collection # 结果 λ python argparse_action.py -s value simple_value = value constant_value = None boolean_switch = False collection = [] const_collection = [] λ python argparse_action.py -c simple_value = None constant_value = value-to-store boolean_switch = False collection = [] const_collection = [] λ python argparse_action.py -t simple_value = None constant_value = None boolean_switch = True collection = [] const_collection = [] λ python argparse_action.py -f simple_value = None constant_value = None boolean_switch = False collection = [] const_collection = [] λ python argparse_action.py -a one -a two -a three simple_value = None constant_value = None boolean_switch = False collection = ['one', 'two', 'three'] const_collection = [] λ python argparse_action.py -B -A simple_value = None constant_value = None boolean_switch = False collection = [] const_collection = ['value-2-to-append', 'value-1-to-append'] λ python argparse_action.py --version argparse_action.py 1.0
咱们常常会遇到不少解析器都会须要相同的参数,例如都须要输入用户名密码,这样咱们能够定义一个父解析器定义common的规则,子解析器能够集成,而且扩展。若是定义了相同的参数便会产生冲突。argparse有两个内置的冲突处理器error
(默认)和resolve
,resolve
会基于冲突选项的添加顺序来选择一个参数处理器,后添加覆盖老规则。咱们应该尽可能避免冲突,因此父解析器通常不定义帮助信息。下面举个简单的例子。
首先定义父解析器以下:
parser = argparse.ArgumentParser(description='parent 2', add_help=False) parser.add_argument('-p', '--password', help='What is your passwrd') parser.add_argument('-user', '--username', help='What is your username') parser.add_argument('-m', '--female', help='What is your female') args = parser.parse_args() print(args) # 结果 λ python arg_parent.py -h usage: arg_parent.py [-p PASSWORD] [-user USERNAME] [-m FEMALE] arg_parent.py: error: unrecognized arguments: -h λ python arg_parent.py -p 123 -user ling -m man Namespace(female='man', password='123', username='ling')
子解析器:集成而且重写
import arg_parent parser = argparse.ArgumentParser(description='son 1', parents=[arg_parent.parser], conflict_handler='resolve') parser.add_argument('-w', '--weather', help="What's the weather") parser.add_argument('-m', '--female', action='store_const', const='TRUE', help='What is your female') args = parser.parse_args() print(args) # 结果 λ python arg_son.py -m -w cold -p 123 Namespace(female='TRUE', password='123', username=None, weather='cold') λ python arg_son.py -m man usage: arg_son.py [-h] [-p PASSWORD] [-user USERNAME] [-w WEATHER] [-m] arg_son.py: error: unrecognized arguments: man
目前只用到了以上特性,还有一些特性就不一一介绍了,后续用到再补充。