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 相关文章推荐
详解Django缓存处理中Vary头部的使用
Jul 24 Python
详解使用 pyenv 管理多个版本 python 环境
Oct 19 Python
Python之reload流程实例代码解析
Jan 29 Python
Python使用matplotlib绘制随机漫步图
Aug 27 Python
详解Python time库的使用
Oct 10 Python
python多线程并发及测试框架案例
Oct 15 Python
python set集合使用方法解析
Nov 05 Python
简单了解django文件下载方式
Feb 10 Python
基于pygame实现童年掌机打砖块游戏
Feb 25 Python
如何基于Python pygame实现动画跑马灯
Nov 18 Python
pycharm无法导入lxml的解决办法
Mar 31 Python
python 判断字符串当中是否包含字符(str.contain)
Jun 01 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绘图之在图片上写中文和英文的方法
2015/01/24 PHP
php快速查找数据库中恶意代码的方法
2015/04/01 PHP
详解PHP中的Traits
2015/07/29 PHP
微信公众平台DEMO(PHP)
2016/05/04 PHP
Extjs Ajax 乱码问题解决方案
2009/04/15 Javascript
input按钮的事件处理大全
2010/12/10 Javascript
jQuery cdn使用介绍
2013/05/08 Javascript
ScrollDown的基本操作示例
2013/06/09 Javascript
javascript中call和apply方法浅谈
2013/09/27 Javascript
js的toLowerCase方法用法实例
2015/01/27 Javascript
手机端页面rem宽度自适应脚本
2015/05/20 Javascript
noty ? jQuery通知插件全面解析
2016/05/18 Javascript
Node.js中使用jQuery的做法
2016/08/17 Javascript
jQuery自定义组件(导入组件)
2016/11/08 Javascript
JQuery 获取Dom元素的实例讲解
2017/07/08 jQuery
js判断输入框不能为空格或null值的实现方法
2018/03/02 Javascript
AngularJs分页插件使用详解
2018/06/30 Javascript
vue-router 起步步骤详解
2019/03/26 Javascript
vue如何自动化打包测试环境和正式环境的dist/test文件
2019/06/06 Javascript
微信小程序实现Swiper轮播图效果
2019/11/22 Javascript
解决echarts echarts数据动态更新和dataZoom被重置问题
2020/07/20 Javascript
详解Python中的正则表达式的用法
2015/04/09 Python
Python实现的矩阵转置与矩阵相乘运算示例
2019/03/26 Python
Python实现的ftp服务器功能详解【附源码下载】
2019/06/26 Python
python单例模式原理与创建方法实例分析
2019/10/26 Python
使用OpenCV获取图像某点的颜色值,并设置某点的颜色
2020/06/02 Python
vscode配置anaconda3的方法步骤
2020/08/08 Python
使用Python画了一棵圣诞树的实例代码
2020/11/27 Python
Matplotlib配色之Colormap详解
2021/01/05 Python
微软澳洲官方网站:Microsoft Australia
2017/01/10 全球购物
ET Mall东森购物网:东森严选
2017/03/06 全球购物
什么是smarty? Smarty的优点是什么?
2013/08/11 面试题
J2EE中的容器都包括哪些
2013/08/21 面试题
办公室人员先进事迹
2014/01/27 职场文书
外联部演讲稿
2014/05/24 职场文书
MySQL利用UNION连接2个查询排序失效详解
2021/11/20 MySQL