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中关于字符串对象的一些基础知识
Apr 08 Python
Python二叉树的遍历操作示例【前序遍历,中序遍历,后序遍历,层序遍历】
Dec 24 Python
对Python3 * 和 ** 运算符详解
Feb 16 Python
Python Opencv实现图像轮廓识别功能
Mar 23 Python
python文本数据处理学习笔记详解
Jun 17 Python
如何用Python制作微信好友个性签名词云图
Jun 28 Python
numpy中的meshgrid函数的使用
Jul 31 Python
Python实现屏幕录制功能的代码
Mar 02 Python
python如何解析复杂sql,实现数据库和表的提取的实例剖析
May 15 Python
Python datetime 如何处理时区信息
Sep 02 Python
Ubuntu 20.04安装Pycharm2020.2及锁定到任务栏的问题(小白级操作)
Oct 29 Python
python实现无边框进度条的实例代码
Dec 30 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
smarty简单入门实例
2014/11/28 PHP
php在数组中查找指定值的方法
2015/03/17 PHP
php修改上传图片尺寸的方法
2015/04/14 PHP
yii分页组件用法实例分析
2015/12/28 PHP
Laravel中Trait的用法实例详解
2016/03/16 PHP
PHP使用内置函数生成图片的方法详解
2016/05/09 PHP
javascript编程起步(第七课)
2007/02/27 Javascript
javascript 学习之旅 (3)
2009/02/05 Javascript
JavaScript toFixed() 方法
2010/04/15 Javascript
去除html代码里面的script正则方法
2016/05/19 Javascript
关于List.ToArray()方法的效率测试
2016/09/30 Javascript
原生js实现倒计时功能(多种格式调用)
2017/01/12 Javascript
layui框架中layer父子页面交互的方法分析
2017/11/15 Javascript
使用vue-cli编写vue插件的方法
2018/02/26 Javascript
详解vue项目中使用token的身份验证的简单实践
2019/03/08 Javascript
javascript设计模式 ? 访问者模式原理与用法实例分析
2020/04/26 Javascript
vue实现户籍管理系统
2020/05/29 Javascript
Python两个整数相除得到浮点数值的方法
2015/03/18 Python
实例说明Python中比较运算符的使用
2015/05/13 Python
Python聚类算法之基本K均值实例详解
2015/11/20 Python
python如何实现反向迭代
2018/03/20 Python
Python小进度条显示代码
2019/03/05 Python
python打包exe开机自动启动的实例(windows)
2019/06/28 Python
python使用PIL和matplotlib获取图片像素点并合并解析
2019/09/10 Python
python GUI库图形界面开发之PyQt5控件数据拖曳Drag与Drop详细使用方法与实例
2020/02/27 Python
CSS3的文字阴影—text-shadow的使用方法
2012/12/25 HTML / CSS
Toppik顶丰增发纤维官网:解决头发稀疏
2017/12/30 全球购物
英语专业毕业生自荐信范文
2013/12/31 职场文书
办公室主任岗位职责范本
2015/03/31 职场文书
创业计划书之儿童理发店
2019/09/27 职场文书
创业计划书之养殖业
2019/10/11 职场文书
JavaScript实现显示和隐藏图片
2021/04/29 Javascript
Feign调用全局异常处理解决方案
2021/06/24 Java/Android
Python 游戏大作炫酷机甲闯关游戏爆肝数千行代码实现案例进阶
2021/10/16 Python
高性能跳频抗干扰宽带自组网电台
2022/02/18 无线电
使用vue判断当前环境是安卓还是IOS
2022/04/12 Vue.js