argparse 库的使用
如果您接触过命令行的话,一定感受过命令工具的使用,会有个参数的概念,比如以列表的形式列出当前目录下的所有可见文件:ls -l
。进行python开发的时候,也许最终会以命令行工具的形式工作,可能需要对命令参数进行处理,那么可以使用 sys.argv
获取命令输入的参数列表,进行分析判断做相应处理,但随着参数项增多,这种方式会越来越复杂,而本文将要介绍的 argparse 库,会使参数的管理变得优雅,下面一起看一下怎么使用吧!
本文就不用解释这个参数的概念了吧,相信您对参数这个概念有了自己的感受,开发一个属于自己的命令工具一定很酷,Let’s do it!
初步感受
本文以python3开发为例,以一个简单的示例开始,创建文件 pug.py ,代码:
import argparse
parser = argparse.ArgumentParser()
parser.parse_args()
我们运行初步感受一下:
$ python3 pug.py
$ python3 pug.py --help
usage: pug.py [-h]
optional arguments:
-h, --help show this help message and exit
$ python3 pug.py --verbose
usage: pug.py [-h]
pug.py: error: unrecognized arguments: --verbose
$ python3 pug.py foo
usage: pug.py [-h]
pug.py: error: unrecognized arguments: foo
看看发生了什么:
- 直接运行文件,不加任何参数,没有任何处理;
- 第二次执行加了参数 –help 会打印一定的帮助信息,这个帮助信息中可以看到 –help可以简写为 -h;
- 第三次和第四次执行使用了不支持的参数,打印了错误提醒;
parser.parse_args() 就是参数解析的过程。
Positional arguments 的使用
Positional arguments 怎么翻译比较好呢?看到网上有人叫它 定位参数,我咋觉得叫它 占位参数 会比较贴切呢,无所谓了,还是用它本名 Positional arguments 吧!
更改pug.py代码为:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo")
args = parser.parse_args()
print(args.echo)
执行看看:
$ python3 pug.py
usage: pug.py [-h] echo
pug.py: error: the following arguments are required: echo
$ python3 pug.py -h
usage: pug.py [-h] echo
positional arguments:
echo
optional arguments:
-h, --help show this help message and exit
$ python3 pug.py yeah
yeah
可以看到在方法 add_argument 的帮助下 echo 成功上位,使用命令时必须为echo位置上输上点什么,它才罢休,这里可以简单地认为echo是一个必须赋值的变量。似乎少了点这个参数的帮助信息,不要紧!有方法 add_argument 的加持啥都不怕,此方法有个参数 help,为其指定内容就可以填充帮助信息了,比如这样:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo", help='学您说话!')
args = parser.parse_args()
print(args.echo)
运行看看:
$ python3 pug.py -h
usage: pug.py [-h] echo
positional arguments:
echo 学您说话!
optional arguments:
-h, --help show this help message and exit
下面,我们不能让pug太调皮,得干点实用的事,比如让它算数,那就让它算一个指定整数的平方吧,修改代码如下:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help='您说个数,我就能告诉您这个数的平方!')
args = parser.parse_args()
print(args.square**2)
执行一下:
$ python3 pug.py 2
Traceback (most recent call last):
File "pug.py", line 5, in <module>
print(args.square**2)
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
出错啦!为什么?因为参数默认都是字符串,小狗子pug肯定不会计算字符串的平方吧!add_argument 方法此时笑了,不用担心,它可以为您按类型解析这个参数的值,只需指定方法的参数 type 就可以了:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help='您说个数,我就能告诉您这个数的平方!', type=int)
args = parser.parse_args()
print(args.square**2)
试一下效果:
$ python3 pug.py 2
4
$ python3 pug.py -h
usage: pug.py [-h] square
positional arguments:
square 您说个数,我就能告诉您这个数的平方!
optional arguments:
-h, --help show this help message and exit
小狗子pug可以的!
Optional arguments 的使用
下面一起看一下可选参数(Optional arguments)的使用。
代码更改为:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--sleep", help='让我睡会儿,困死了!')
args = parser.parse_args()
if args.sleep:
print('我睡着了(-_-)zzz,别打搅我!')
看一下小狗子有多懒:
$ python3 pug.py -h
usage: pug.py [-h] [--sleep SLEEP]
optional arguments:
-h, --help show this help message and exit
--sleep SLEEP 让我睡会儿,困死了!
$ python3 pug.py --sleep 1
我睡着了(-_-)zzz,别打搅我!
简单来说,对于睡觉,要么睡着要么没睡,应该是二值,那可以限制这个参数 –sleep 要么 True 要么 False,方法 add_argument 提供了设置参数 action ,设置其为 store_true 即可:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--sleep", help='让我睡会儿,困死了!', action='store_true')
args = parser.parse_args()
if args.sleep:
print('我睡着了(-_-)zzz,别打搅我!')
else:
print('我很清醒,不想睡觉!')
逗一下小狗子pug:
$ python3 pug.py -h
usage: pug.py [-h] [--sleep]
optional arguments:
-h, --help show this help message and exit
--sleep 让我睡会儿,困死了!
$ python3 pug.py --sleep 1
usage: pug.py [-h] [--sleep]
pug.py: error: unrecognized arguments: 1
$ python3 pug.py --sleep
我睡着了(-_-)zzz,别打搅我!
$ python3 pug.py
我很清醒,不想睡觉!
可以看到,运行命令时,如果指定参数 –sleep,那么这个参数值就为 True, 如果没有,那么参数值为 False。如果您了解命令行工具的使用一定会问:短参数的实现会是怎样的?其实很简单:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-s', "--sleep", help='让我睡会儿,困死了!', action='store_true')
args = parser.parse_args()
if args.sleep:
print('我睡着了(-_-)zzz,别打搅我!')
else:
print('我很清醒,不想睡觉!')
叫小狗子pug试一下:
$ python3 pug.py -h
usage: pug.py [-h] [-s]
optional arguments:
-h, --help show this help message and exit
-s, --sleep 让我睡会儿,困死了!
$ python3 pug.py -s
我睡着了(-_-)zzz,别打搅我!
Positional arguments 和 Optional arguments 结合使用
让小狗子睡着觉算数会是咋样的,试一下:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help='您说个数,我就能告诉您这个数的平方!', type=int)
parser.add_argument('-s', "--sleep", help='让我睡会儿,困死了!', action='store_true')
args = parser.parse_args()
answer = args.square ** 2
if args.sleep:
print(f'我睡着了(-_-)zzz都能算数:{answer}!')
else:
print(f'我很清醒,结果是:{answer}!')
让小狗子嚣张嚣张:
$ python3 pug.py -s 3
我睡着了(-_-)zzz都能算数:9!
$ python3 pug.py 3
我很清醒,结果是:9!
$ python3 pug.py -h
usage: pug.py [-h] [-s] square
positional arguments:
square 您说个数,我就能告诉您这个数的平方!
optional arguments:
-h, --help show this help message and exit
-s, --sleep 让我睡会儿,困死了!
小狗子很厉害呀,睡着觉都给算出结果来了,那小狗子睡觉也分状态的吧,熟睡和半睡半醒状态应该会不一样,看一下会怎么样:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help='您说个数,我就能告诉您这个数的平方!', type=int)
parser.add_argument('-s', "--sleep", type=int, help='让我睡会儿,困死了!')
args = parser.parse_args()
answer = args.square ** 2
if args.sleep == 2:
print(f'虽然我睡的很死,但我的耳朵好像还挺好使的的,用耳朵都能算的:{answer}!')
elif args.sleep == 1:
print(f'半睡半醒的我当然听得清你说什么,很简单的题嘛:{answer}!')
else:
print(f'我很清醒,结果是:{answer}!')
那我们考一下小狗子:
$ python3 pug.py 3 -s
usage: pug.py [-h] [-s SLEEP] square
pug.py: error: argument -s/--sleep: expected one argument
$ python3 pug.py 3 -s 1
半睡半醒的我当然听得清你说什么,很简单的题嘛:9!
$ python3 pug.py 3 -s 2
虽然我睡的很死,但我的耳朵好像还挺好使的的,用耳朵都能算的:9!
$ python3 pug.py 3 -s 0
我很清醒,结果是:9!
$ python3 pug.py -h
usage: pug.py [-h] [-s SLEEP] square
positional arguments:
square 您说个数,我就能告诉您这个数的平方!
optional arguments:
-h, --help show this help message and exit
-s SLEEP, --sleep SLEEP
让我睡会儿,困死了!
$ python3 pug.py 3
我很清醒,结果是:9!
简直了,但是这里有个问题,pug睡觉状态并不是很多,如果我们指定其它可能没有必要嘛,能不能对值进行限制呢?当然可以啦,添加参数时给定 choices 就可以啦:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help='您说个数,我就能告诉您这个数的平方!', type=int)
parser.add_argument('-s', "--sleep", type=int, choices=[1, 2], help='让我睡会儿,困死了!')
args = parser.parse_args()
answer = args.square ** 2
if args.sleep == 2:
print(f'虽然我睡的很死,但我的耳朵好像还挺好使的的,用耳朵都能算的:{answer}!')
elif args.sleep == 1:
print(f'半睡半醒的我当然听得清你说什么,很简单的题嘛:{answer}!')
else:
print(f'我很清醒,结果是:{answer}!')
看一下效果:
$ python3 pug.py 3 -s 0
usage: pug.py [-h] [-s {1,2}] square
pug.py: error: argument -s/--sleep: invalid choice: 0 (choose from 1, 2)
$ python3 pug.py -h
usage: pug.py [-h] [-s {1,2}] square
positional arguments:
square 您说个数,我就能告诉您这个数的平方!
optional arguments:
-h, --help show this help message and exit
-s {1,2}, --sleep {1,2}
让我睡会儿,困死了!
效果还可以,现在尝试另一种玩法,先看代码:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help='您说个数,我就能告诉您这个数的平方!', type=int)
parser.add_argument('-s', "--sleep", action='count', help='让我睡会儿,困死了!')
args = parser.parse_args()
answer = args.square ** 2
if args.sleep == 2:
print(f'虽然我睡的很死,但我的耳朵好像还挺好使的的,用耳朵都能算的:{answer}!')
elif args.sleep == 1:
print(f'半睡半醒的我当然听得清你说什么,很简单的题嘛:{answer}!')
else:
print(f'我很清醒,结果是:{answer}!')
再看一下结果:
$ python3 pug.py 3 -s
半睡半醒的我当然听得清你说什么,很简单的题嘛:9!
$ python3 pug.py 3 -ss
虽然我睡的很死,但我的耳朵好像还挺好使的的,用耳朵都能算的:9!
$ python3 pug.py 3 -sss
我很清醒,结果是:9!
$ python3 pug.py 3
我很清醒,结果是:9!
好像第三条有点问题哈,修复一下这个bug:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help='您说个数,我就能告诉您这个数的平方!', type=int)
parser.add_argument('-s', "--sleep", action='count', help='让我睡会儿,困死了!')
args = parser.parse_args()
answer = args.square ** 2
if args.sleep >= 2:
print(f'虽然我睡的很死,但我的耳朵好像还挺好使的的,用耳朵都能算的:{answer}!')
elif args.sleep >= 1:
print(f'半睡半醒的我当然听得清你说什么,很简单的题嘛:{answer}!')
else:
print(f'我很清醒,结果是:{answer}!')
再看一下这次是不是更好了:
$ python3 pug.py 3 -s
半睡半醒的我当然听得清你说什么,很简单的题嘛:9!
$ python3 pug.py 3 -ss
虽然我睡的很死,但我的耳朵好像还挺好使的的,用耳朵都能算的:9!
$ python3 pug.py 3 -sss
虽然我睡的很死,但我的耳朵好像还挺好使的的,用耳朵都能算的:9!
$ python3 pug.py 3
Traceback (most recent call last):
File "pug.py", line 7, in <module>
if args.sleep >= 2:
TypeError: '>=' not supported between instances of 'NoneType' and 'int'
哎呀,好像最后一个让小狗子炸锅了,稍微修理一下它(给参数指定默认值):
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help='您说个数,我就能告诉您这个数的平方!', type=int)
parser.add_argument('-s', "--sleep", action='count', default=0, help='让我睡会儿,困死了!')
args = parser.parse_args()
answer = args.square ** 2
if args.sleep >= 2:
print(f'虽然我睡的很死,但我的耳朵好像还挺好使的的,用耳朵都能算的:{answer}!')
elif args.sleep >= 1:
print(f'半睡半醒的我当然听得清你说什么,很简单的题嘛:{answer}!')
else:
print(f'我很清醒,结果是:{answer}!')
看一下是否正常了:
$ python3 pug.py 3
我很清醒,结果是:9!
OKay! 效果不错,小狗子修炼得不错了!
互斥参数
有的时候小狗子的行为是互斥的,比如睡着觉的时候不能跳舞,跳舞的时候没有在睡觉,所以呀,有的时候还需要互斥参数的使用。
使用起来并不复杂,丰富一下我们的小狗子:
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('-s', "--sleep", action='store_true', help='让我睡会儿,困死了!')
group.add_argument('-d', '--dance', action='store_true', help='好开心,让我跳会儿舞!')
parser.add_argument("square", help='您说个数,我就能告诉您这个数的平方!', type=int)
args = parser.parse_args()
answer = args.square ** 2
if args.sleep:
print(f'睡觉的我依然给力,{args.square} 的平方是 {answer}!')
elif args.dance:
print(f'跳舞的时候,我的大脑非常活跃,所以,{args.square} 的平方是 {answer}!')
else:
print(f'{args.square} 的平方是 {answer}!')
现在小狗子点了新技能,展示一下:
$ python3 pug.py -h
usage: pug.py [-h] [-s | -d] square
positional arguments:
square 您说个数,我就能告诉您这个数的平方!
optional arguments:
-h, --help show this help message and exit
-s, --sleep 让我睡会儿,困死了!
-d, --dance 好开心,让我跳会儿舞!
$ python3 pug.py 5
5 的平方是 25!
$ python3 pug.py -s 5
睡觉的我依然给力,5 的平方是 25!
$ python3 pug.py -d 5
跳舞的时候,我的大脑非常活跃,所以,5 的平方是 25!
$ python3 pug.py -d -s 5
usage: pug.py [-h] [-s | -d] square
pug.py: error: argument -s/--sleep: not allowed with argument -d/--dance
对了,我们应该让小狗子可以自我介绍,在初始化参数分析器的时候添加描述就好了:
import argparse
parser = argparse.ArgumentParser(description='我是一只快乐的哈巴狗,我会算整数的平方哦!而且跳着舞或者睡着觉的时候我依然可以呢!')
group = parser.add_mutually_exclusive_group()
group.add_argument('-s', "--sleep", action='store_true', help='让我睡会儿,困死了!')
group.add_argument('-d', '--dance', action='store_true', help='好开心,让我跳会儿舞!')
parser.add_argument("square", help='您说个数,我就能告诉您这个数的平方!', type=int)
args = parser.parse_args()
answer = args.square ** 2
if args.sleep:
print(f'睡觉的我依然给力,{args.square} 的平方是 {answer}!')
elif args.dance:
print(f'跳舞的时候,我的大脑非常活跃,所以,{args.square} 的平方是 {answer}!')
else:
print(f'{args.square} 的平方是 {answer}!')
让它好好的自我介绍一下自己吧:
$ python3 pug.py -h
usage: pug.py [-h] [-s | -d] square
我是一只快乐的哈巴狗,我会算整数的平方哦!而且跳着舞或者睡着觉的时候我依然可以呢!
positional arguments:
square 您说个数,我就能告诉您这个数的平方!
optional arguments:
-h, --help show this help message and exit
-s, --sleep 让我睡会儿,困死了!
-d, --dance 好开心,让我跳会儿舞!
总结
作者希望您通过与小哈巴狗的玩耍,很快学会 argparse 库的使用,我们也要像它一样快乐才好!(◐‿◑)