Python中最好用的命令行参数解析工具(argparse)


Posted in Python onAugust 23, 2019

Python 做为一个脚本语言,可以很方便地写各种工具。当你在服务端要运行一个工具或服务时,输入参数似乎是一种硬需(当然你也可以通过配置文件来实现)。

如果要以命令行执行,那你需要解析一个命令行参数解析的模块来帮你做这个苦力活。

Python 本身就提供了三个命令行参数解析模块,我这里罗列一下它们的大致情况供你了解。

  • getopt,只能简单的处理命令行参数
  • optparse,功能强大,易于使用,可以方便地生成标准的、符合Unix/Posix 规范的命令行说明。
  • argparse,使其更加容易的编写用户友好的命令行接口。它所需的程序进程了参数定义,argparse将更好的解析sys.argv。同时argparse模块还能自动生成帮助及用户输入错误参数时的提示信息。

很多初学者可能会使用getopt,上手简单功能也简单。比如说optget无法解析一个参数多个值的情况,如 --file file1 file2 file3,而 optparse 实际上我没有用过,但是考虑到它在Python2.7后就已经弃用不再维护,我们通常也不会使用它。

接下来只剩下 argparse 这一神器,它几乎能满足我对命令解析器的所有需求。它支持解析一参数多值,可以自动生成help命令和帮助文档,支持子解析器,支持限制参数取值范围等等功能。

0. HelloWorld

不管学习什么东西,首先第一步都应该是掌握它的大体框架。

而 使用 argparse 前,框架很简单,你只需要记住这三行。

# mytest.py
import argparse
parser = argparse.ArgumentParser(description="used for test")

args = parser.parse_args()

现在可以尝试一下

[root@localhost ~]# python mytest.py -h
usage: mytest.py [-h]

used for test

optional arguments:
 -h, --help show this help message and exit
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# python mytest.py
[root@localhost ~]#

已经可以使用了。

1. 入门配置

这里先讲一下,比较常用的参数配置。

  • 调试:debug
  • 版本号:version
import argparse
parser = argparse.ArgumentParser()

parser.add_argument('--version', '-v', action='version',
          version='%(prog)s version : v 0.01', help='show the version')

parser.add_argument('--debug', '-d', action='store_true',
          help='show the version',
          default=False)

args = parser.parse_args()
print("=== end ===")

上面debug处的配置,需要讲一下的是 action='store_true' 和 default = False 的作用和区别

  • store_true:一旦指定了 -d 或者 --debug ,其值就为 True,store_false则相反
  • default=False:未指定 -d 或者 --debug,其值就默认为False

当我们执行 python mytest.py -v,就会打印 version 里的内容。

[root@localhost ~]# python mytest.py -v
mytest.py version : v 0.01
[root@localhost ~]#

一旦执行时,指定了参数 -v ,执行到 parser.parse_args() 就会退出程序,不会打印最后的 === end ===

2. 参数种类

参数可分为 必选参数(positional arguments) 和 可选参数(optional arguments)。

在argsparse 里如何实现呢?

必选参数

用单词做参数,默认就为必选参数

# mytest.py
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("name")

args = parser.parse_args()

print(args.name)

不指定name参数运行一下:python mytest.py

[root@localhost ~]# python mytest.py 
usage: mytest.py [-h] name
mytest.py: error: too few arguments
[root@localhost ~]#

如预期一样,报错了,说缺少参数。那我们指定一下:python mytest.py name wangbm

[root@localhost ~]# python mytest.py wangbm
wangbm
[root@localhost ~]#

可选参数

有两种方式:

  • 单下划线 - 来指定的短参数,如-h;
  • 双下划线 -- 来指定的长参数,如--help
# mytest.py
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbosity", help="increase output verbosity")

args = parser.parse_args()

if args.verbosity:
 print("verbosity turned on")
else:
  print("verbosity turned off")

试着运行一下 python mytest.py,不会报错。

[root@localhost ~]# python mytest.py
verbosity turned off
[root@localhost ~]#

3. 参数类型

有的参数,是字符串,有的参数,是数值。

为了对命令行中的参数进行有效的约束,我们可以事先对参数的类型进行声明。argparse 会对参数进行校验,不通过时,会直接抛出错误。

# mytest.py
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("name")
parser.add_argument("age", type=int)

args = parser.parse_args()

print(args.name)
print(args.age)

测试一下?h。

[root@localhost ~]# python mytest.py wangbm eighteen
usage: mytest.py [-h] name age
mytest.py: error: argument age: invalid int value: 'eighteen'
[root@localhost ~]# 
[root@localhost ~]# python mytest.py wangbm 18
wangbm
18
[root@localhost ~]#

你看,写 eighteen 就不行,提示类型不合法,只有写 18 才行。

4. 互斥参数

有些参数,是互斥的,有你无我。比如,性别。

在 argparse 中如何实现?

import argparse

parser = 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 ~]# python mytest.py -f
[root@localhost ~]# python mytest.py -m
[root@localhost ~]# python mytest.py -m -f 
usage: mytest.py [-h] [-m | -f]
mytest.py: error: argument -f/--female: not allowed with argument -m/--male
[root@localhost ~]#

5. 可选值

如果是性别,可以像上面那样放在两个参数里然后用互斥组来约束,也可以放在一个参数里,在argparse里限制再在外层做判断。

# mytest.py
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-g", "--gender", default='male',
          choices=['male', 'female'])

args = parser.parse_args()
print(args.gender)

试着执行一下,发现性别只能是男或女,不能为人妖。

[root@localhost ~]# python mytest.py --gender male
male
[root@localhost ~]# python mytest.py --gender female
female
[root@localhost ~]# 
[root@localhost ~]# 
[root@localhost ~]# python mytest.py --gender other
usage: mytest.py [-h] [-g {male,female}]
mytest.py: error: argument -g/--gender: invalid choice: 'other' (choose from 'male', 'female')
[root@localhost ~]#

6. 指定文件

经常会有那种要在脚本中指定配置文件或者其他文件的需求。可以使用下面的配置

import argparse
parser = argparse.ArgumentParser()

parser.add_argument('--file', '-f', action='append',
          dest='files',
          help=('additional yaml configuration files to use'),
          type=argparse.FileType('rb'))
          
args = parser.parse_args()

dest=files,是说将命令行中,--file 的参数值赋值给变量files,你可以用args.files访问。

action=append,由于我们会有指定多个文件的需求,那就指定多次--file ,argparse会将其放在一个list里。

type=argparse.FileType('rb'),既然是指定文件,那么参数应该为路径,并指定打开模式为rb,如果如果要取得文件内容,可以用 args.files[0].read()

7. 子解析器

如果你对命令行,有过足够多的接触,就会知道有些情况下会有子解析器。

这里我以自己工作中,碰到的例子来举个例子。

cloud-init --debug single -name mymodule

其中 single 后面是一个子解析器。

# cloud-init.py

def main_single(name, args):
  print("name: ", name)
  print("args: ", args)
  print("I am main_single")

# 添加一个子解析器
subparsers = parser.add_subparsers()

parser_single = subparsers.add_parser('single',help='run a single module')

# 对single 子解析器添加 action 函数。
parser_single.set_defaults(action=('single', main_single))

# require=True,是说如果命令行指定了single解析器,就必须带上 --name 的参数。
parser_single.add_argument("--name", '-n', action="store",
              help="module name to run",
              required=True)

args = parser.parse_args()

(name, functor) = args.action
if name in ["single"]:
  functor(name, args)

执行命令cloud-init single -name mymodule,输出如下

name:  single
args:  Namespace(action=('single', <function main_single at 0x0000000003F161E0>), debug=False, file=None, name='mymodule')
I am main_single

以上就是关于 argparse 工具的使用方法,你学会了吗?希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python读取与写入csv格式文件的示例代码
Dec 16 Python
如何使用Python的Requests包实现模拟登陆
Apr 27 Python
Python访问MongoDB,并且转换成Dataframe的方法
Oct 15 Python
Python3+OpenCV2实现图像的几何变换(平移、镜像、缩放、旋转、仿射)
May 13 Python
Python3.8对可迭代解包的改进及用法详解
Oct 15 Python
pytorch .detach() .detach_() 和 .data用于切断反向传播的实现
Dec 27 Python
pytorch1.0中torch.nn.Conv2d用法详解
Jan 10 Python
python 操作mysql数据中fetchone()和fetchall()方式
May 15 Python
python中tkinter窗口位置\坐标\大小等实现示例
Jul 09 Python
几款Python编译器比较与推荐(小结)
Oct 15 Python
使用Python爬取小姐姐图片(beautifulsoup法)
Feb 11 Python
Python 文本滚动播放器的实现代码
Apr 25 Python
详解Python并发编程之创建多线程的几种方法
Aug 23 #Python
详解Python并发编程之从性能角度来初探并发编程
Aug 23 #Python
python Kmeans算法原理深入解析
Aug 23 #Python
Python高级特性 切片 迭代解析
Aug 23 #Python
Python 合并多个TXT文件并统计词频的实现
Aug 23 #Python
Python 调用 Windows API COM 新法
Aug 22 #Python
详解Python文件修改的两种方式
Aug 22 #Python
You might like
PHP is_array() 检测变量是否是数组的实现方法
2016/06/13 PHP
PHP ADODB生成下拉列表框功能示例
2018/05/29 PHP
掌握PHP垃圾回收机制详解
2019/03/13 PHP
关于viewport,Ext.panel和Ext.form.panel的关系
2009/05/07 Javascript
Javascript学习笔记一 之 数据类型
2010/12/15 Javascript
jQuery+css实现图片滚动效果(附源码)
2013/03/18 Javascript
jquery入门必备的基本认识及实例(整理)
2013/06/24 Javascript
javascript实现跳转菜单的具体方法
2013/07/05 Javascript
js Array操作的最简短最容易理解方法
2013/12/09 Javascript
JS创建对象的写法示例
2016/11/04 Javascript
Vue.js 实现微信公众号菜单编辑器功能(一)
2018/05/08 Javascript
jQuery模拟html下拉多选框的原生实现方法示例
2019/05/30 jQuery
微信小程序获取复选框全选反选选中的值(实例代码)
2019/12/17 Javascript
vue使用nprogress加载路由进度条的方法
2020/06/04 Javascript
[45:59]完美世界DOTA2联赛PWL S2 FTD vs GXR 第二场 11.22
2020/11/24 DOTA
基于python的汉字转GBK码实现代码
2012/02/19 Python
Python递归函数定义与用法示例
2017/06/02 Python
Python3.6.0+opencv3.3.0人脸检测示例
2018/05/25 Python
python实现统计代码行数的小工具
2019/09/19 Python
python求质数列表的例子
2019/11/24 Python
Python实现图像的垂直投影示例
2020/01/17 Python
解决tensorboard多个events文件显示紊乱的问题
2020/02/15 Python
python 画条形图(柱状图)实例
2020/04/24 Python
Python多线程正确用法实例解析
2020/05/30 Python
Python命名空间及作用域原理实例解析
2020/08/12 Python
Html5 页面适配iPhoneX(就是那么简单)
2019/09/05 HTML / CSS
迪卡侬比利时官网:Decathlon比利时
2019/12/28 全球购物
广告业务员岗位职责
2014/02/06 职场文书
酒店总经理岗位职责
2014/03/17 职场文书
庆六一文艺汇演活动方案
2014/08/26 职场文书
学校个人对照检查材料
2014/08/26 职场文书
2014年人力资源工作总结
2014/11/19 职场文书
2015年社区宣传工作总结
2015/05/20 职场文书
党员干部学习十八届五中全会精神心得体会
2016/01/05 职场文书
Python中requests做接口测试的方法
2021/05/30 Python
深入理解python协程
2021/06/15 Python