Argparse简易教程
译者:likebeta
本教程是对于Python标准库中推荐使用的命令行解析模块argparse的简单介绍。
PS:还有其他两个模块实现这一功能,getopt(等同于C语言中的getopt())和弃用的optparse。因为argparse是基于optparse,所以用法很类似。
概念
让我们先用ls
来展示这篇教程将要介绍的相关特性:
$ ls
cpython devguide prog.py pypy rm-unused-function.patch
$ ls pypy
ctypes_configure demo dotviewer include lib_pypy lib-python ...
$ ls -l
total 20
drwxr-xr-x 19 wena wena 4096 Feb 18 18:51 cpython
drwxr-xr-x 4 wena wena 4096 Feb 8 12:04 devguide
-rwxr-xr-x 1 wena wena 535 Feb 19 00:05 prog.py
drwxr-xr-x 14 wena wena 4096 Feb 7 00:59 pypy
-rw-r--r-- 1 wena wena 741 Feb 18 01:01 rm-unused-function.patch
$ 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.
...
从上面的四个命令,我们可以了解一些概念:
-
ls
命令在没有参数的情况下也是可以使用的。默认显示当前目录的内容。 - 如果想让它展示不同,需要给它更多的参数。这个例子中,我们想让它显示目录
pypy
,需要指定必要的参数。因为程序需要基于这些参数确定做些什么。这个概念类似cp
, 比如最常见的cp SRC DST
。第一个参数表示你要复制什么,第二个参数表示复制到哪里去。 - 现在,我想要改变程序的行为。在示例中,我们让它显示更多的信息,不仅仅是文件名,这里的
-l
就是一个可选参数。 - 最后是一个帮助文档的片段。这些帮助对于没有使用过这个程序的人很有帮助,他们可以通过简单的阅读,就可以了解程序的用法。
基础
让我们从一个简单的例子开始,它(几乎)什么都不做:
import argparse
parser = argparse.ArgumentParser()
parser.parse_args()
运行:
$ python prog.py
$ python prog.py --help
usage: prog.py [-h]
optional arguments:
-h, --help show this help message and exit
$ python prog.py --verbose
usage: prog.py [-h]
prog.py: error: unrecognized arguments: --verbose
$ python prog.py foo
usage: prog.py [-h]
prog.py: error: unrecognized arguments: foo
结果分析:
- 不加任何参数运行,什么也不显示,没有什么用。
- 第二条展示了
argparse
模块的好处,几乎什么都不做,却得到了一个很有用的帮助信息。 -
--help
参数可简写成-h
,是唯一预设的(不需要指定)。
定位参数
例子:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo")
args = parser.parse_args()
print args.echo
运行:
$ python prog.py
usage: prog.py [-h] echo
prog.py: error: the following arguments are required: echo
$ python prog.py --help
usage: prog.py [-h] echo
positional arguments:
echo
optional arguments:
-h, --help show this help message and exit
$ python prog.py foo
foo
结果分析:
- 我们用到了方法
add_argument()
,用来指定程序需要接受的命令参数,本例中的echo
。 - 现在运行程序必须指定一个参数。
- 方法
parse_args()
通过分析指定的参数返回一些数据,如本例中的echo
。 - 像魔法一样,
argparse
自动生成这些变量,你可能已经注意到变量echo
和我们指定的参数相同。
虽然现在帮助信息已经很美观了,但是还不够好。例如我们知道echo
是个定位参数,但是却不知道该参数的意思,只能通过猜或者读源码。下面,我们可以让它更有帮助:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("echo", help="echo the string you use here")
args = parser.parse_args()
print args.echo
运行:
$ python prog.py -h
usage: prog.py [-h] echo
positional arguments:
echo echo the string you use here
optional arguments:
-h, --help show this help message and exit
再修改下:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number")
args = parser.parse_args()
print args.square**2
运行如下:
$ python prog.py 4
Traceback (most recent call last):
File "prog.py", line 5, in <module>
print args.square**2
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
运行有点问题,因为如果不指定参数类型,argparse
默认它是字符串。因此我们需要告诉argparse
该参数是整型。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", help="display a square of a given number",
type=int)
args = parser.parse_args()
print args.square**2
运行:
$ python prog.py 4
16
$ python prog.py four
usage: prog.py [-h] square
prog.py: error: argument square: invalid int value: 'four'
可以运行了,程序能够在执行前过滤一些错误的参数输入。
可选参数
以上,展示了定位参数的用法。下面让我们来看看如何添加可选参数:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbosity", help="increase output verbosity")
args = parser.parse_args()
if args.verbosity:
print "verbosity turned on"
输出:
$ python prog.py --verbosity 1
verbosity turned on
$ python prog.py
$ python prog.py --help
usage: prog.py [-h] [--verbosity VERBOSITY]
optional arguments:
-h, --help show this help message and exit
--verbosity VERBOSITY
increase output verbosity
$ python prog.py --verbosity
usage: prog.py [-h] [--verbosity VERBOSITY]
prog.py: error: argument --verbosity: expected one argument
结果分析:
- 当指定
--verbosity
时程序就显示一些东西,没指定的时候就不显示。 - 这个参数事实上是可选的,不指定它也不会出错。如果不指定可选的参数,对应的变量就被设置为None,比如本例中的
args.verbosity
, 这就是为什么示例中的 if 没有执行的原因。 - 帮助信息发生了点变化
- 当我们使用可选参数
--verbosity
时,也必须指定一些值。
上面的示例中可选参数--verbosity
后面接受任意的整型值,但是对于简单的程序,实际上只需要两种值,True
或者False
。因此可以修改上面的代码:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", help="increase output verbosity",
action="store_true")
args = parser.parse_args()
if args.verbose:
print "verbosity turned on"
运行:
$ python prog.py --verbose
verbosity turned on
$ python prog.py --verbose 1
usage: prog.py [-h] [--verbose]
prog.py: error: unrecognized arguments: 1
$ python prog.py --help
usage: prog.py [-h] [--verbose]
optional arguments:
-h, --help show this help message and exit
--verbose increase output verbosity
结果分析:
- 现在多加一个标志来替代必须给出一些值,并修改了名称来表达我们的意思。注意现在指定了一个新的关键词
action
,并且赋值为store_ture
。如果指定了这个可选参数,args.verbose
就赋值为True
,否则就为False
。 - 多指定了值,它就会发出错误提示。
- 注意帮助文档有什么不同
简写
如果你很熟悉命令行,你可能已经注意到我在上面已经提到了参数的简写,非常的简单:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", help="increase output verbosity",
action="store_true")
args = parser.parse_args()
if args.verbose:
print "verbosity turned on"
运行如下:
$ python prog.py -v
verbosity turned on
$ python prog.py --help
usage: prog.py [-h] [-v]
optional arguments:
-h, --help show this help message and exit
-v, --verbose increase output verbosity
注意帮助信息也有相应的变化。
混合使用定位参数和可选参数
再复杂一点:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbose", action="store_true",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbose:
print "the square of {} equals {}".format(args.square, answer)
else:
print answer
运行:
$ python prog.py
usage: prog.py [-h] [-v] square
prog.py: error: the following arguments are required: square
$ python prog.py 4
16
$ python prog.py 4 --verbose
the square of 4 equals 16
$ python prog.py --verbose 4
the square of 4 equals 16
- 为了让程序复杂点,我们重新加上了定位参数。
- 注意到参数的顺序是没有影响的。
来看看为程序加上处理重复参数的能力会怎么样:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int,
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
运行:
$ python prog.py 4
16
$ python prog.py 4 -v
usage: prog.py [-h] [-v VERBOSITY] square
prog.py: error: argument -v/--verbosity: expected one argument
$ python prog.py 4 -v 1
4^2 == 16
$ python prog.py 4 -v 2
the square of 4 equals 16
$ python prog.py 4 -v 3
16
除了最后一个暴露了一个bug,其他的看起都来运行良好。让我们通过限制--verbosity
后面跟的值来修正:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
运行:
$ python prog.py 4 -v 3
usage: prog.py [-h] [-v {0,1,2}] square
prog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2)
$ python prog.py 4 -h
usage: prog.py [-h] [-v {0,1,2}] square
positional arguments:
square display a square of a given number
optional arguments:
-h, --help show this help message and exit
-v {0,1,2}, --verbosity {0,1,2}
increase output verbosity
注意帮助信息和错误信息都发生了变化。
现在让我们用一种更常用的方法来处理,类似CPython
处理自己的参数(参考python --help
):
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display the square of a given number")
parser.add_argument("-v", "--verbosity", action="count",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity == 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
我们引入了另一个关键词count
来统计可选参数出现的次数:
$ python prog.py 4
16
$ python prog.py 4 -v
4^2 == 16
$ python prog.py 4 -vv
the square of 4 equals 16
$ python prog.py 4 --verbosity --verbosity
the square of 4 equals 16
$ python prog.py 4 -v 1
usage: prog.py [-h] [-v] square
prog.py: error: unrecognized arguments: 1
$ python prog.py 4 -h
usage: prog.py [-h] [-v] square
positional arguments:
square display a square of a given number
optional arguments:
-h, --help show this help message and exit
-v, --verbosity increase output verbosity
$ python prog.py 4 -vvv
16
- 和前面的版本相比这里多了一个关键词(类似
action="store_true"
)。 - 行为上也类似
store_true
。 -
count
关键词的示范,大家可能在其他地方已经看过了。 - 就像
store_ture
,如果不指定-v
,响应变量就会被设置为None
。 - 指定完整的名称和简写效果是一样的。
- 但是不爽的是,帮助信息并没有做出有用的提示,不过可以通过修改
help
来改善这个问题。 - 最后那个输出又暴露了程序的bug
修改一下:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", action="count",
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
# bugfix: replace == with >=
if args.verbosity >= 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity >= 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
运行如下:
$ python prog.py 4 -vvv
the square of 4 equals 16
$ python prog.py 4 -vvvv
the square of 4 equals 16
$ python prog.py 4
Traceback (most recent call last):
File "prog.py", line 11, in <module>
if args.verbosity >= 2:
TypeError: unorderable types: NoneType() >= int()
- 第一个输出是正确的,修正了上个版本的问题,参数出现次数>=2时都能显示详细的信息。
- 第三个输出还是有问题
再来修改下:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
help="display a square of a given number")
parser.add_argument("-v", "--verbosity", action="count", default=0,
help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity >= 2:
print "the square of {} equals {}".format(args.square, answer)
elif args.verbosity >= 1:
print "{}^2 == {}".format(args.square, answer)
else:
print answer
我们又加入了一个关键词default
。设置它的默认值为0,这样可以让它兼容其他整型。注意,如果一个可选参数没有指定,它就会被设置成None
,None
是不能和整型比较的(触发[TypeError][5]异常
)。
运行结果:
$ python prog.py 4
16
你可以使用我们所学来做很多事情,但是这仅仅是皮毛而已。argparse
模块非常强大,下面来看看更多的用法。
高级用法
如果我们想扩展程序的功能,而不仅仅是求平方:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
parser.add_argument("-v", "--verbosity", action="count", default=0)
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
print "{} to the power {} equals {}".format(args.x, args.y, answer)
elif args.verbosity >= 1:
print "{}^{} == {}".format(args.x, args.y, answer)
else:
print answer
输出:
$ python prog.py
usage: prog.py [-h] [-v] x y
prog.py: error: the following arguments are required: x, y
$ python prog.py -h
usage: prog.py [-h] [-v] x y
positional arguments:
x the base
y the exponent
optional arguments:
-h, --help show this help message and exit
-v, --verbosity
$ python prog.py 4 2 -v
4^2 == 16
截止到目前,我们都在利用详细的级别来改变输出,下面的示例演示了利用详细的级别来显示更多输出:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
parser.add_argument("-v", "--verbosity", action="count", default=0)
args = parser.parse_args()
answer = args.x**args.y
if args.verbosity >= 2:
print "Running '{}'".format(__file__)
if args.verbosity >= 1:
print "{}^{} ==".format(args.x, args.y),
print answer
输出:
$ python prog.py 4 2
16
$ python prog.py 4 2 -v
4^2 == 16
$ python prog.py 4 2 -vv
Running 'prog.py'
4^2 == 16
参数冲突
迄今为止,我们已经使用到了[argparse.ArgumentParser][6]
的两个方法,来看看他的另一个方法add_mutually_exclusive_group()
。它可以让我们指定某个参数和其他参数冲突。下面来修改下程序以对这个新方法有更多的了解:我们将加入参数--quiet
,它和参数--verbose
冲突,不能同时指定:
import argparse
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
answer = args.x**args.y
if args.quiet:
print answer
elif args.verbose:
print "{} to the power {} equals {}".format(args.x, args.y, answer)
else:
print "{}^{} == {}".format(args.x, args.y, answer)
程序很简单,为了演示冲突,去掉了其他功能特性展示,运行结果:
$ python prog.py 4 2
4^2 == 16
$ python prog.py 4 2 -q
16
$ python prog.py 4 2 -v
4 to the power 2 equals 16
$ python prog.py 4 2 -vq
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
$ python prog.py 4 2 -v --quiet
usage: prog.py [-h] [-v | -q] x y
prog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose
很好理解,我们添加最后那个输出是为了展示灵活性,比如,指定参数时可以同时混用参数全称和简写。
通过前面的学习,为了以防万一,你可能想通过帮助信息来告诉用户如何使用你的程序:
import argparse
parser = argparse.ArgumentParser(description="calculate X to the power of Y")
group = parser.add_mutually_exclusive_group()
group.add_argument("-v", "--verbose", action="store_true")
group.add_argument("-q", "--quiet", action="store_true")
parser.add_argument("x", type=int, help="the base")
parser.add_argument("y", type=int, help="the exponent")
args = parser.parse_args()
answer = args.x**args.y
if args.quiet:
print answer
elif args.verbose:
print "{} to the power {} equals {}".format(args.x, args.y, answer)
else:
print "{}^{} == {}".format(args.x, args.y, answer)
注意下面的帮助信息,[-v | -q]
表明了可以使用-v
或者-q
,但是不能同时使用。
$ python prog.py --help
usage: prog.py [-h] [-v | -q] x y
calculate X to the power of Y
positional arguments:
x the base
y the exponent
optional arguments:
-h, --help show this help message and exit
-v, --verbose
-q, --quiet
Argparse简易教程的更多相关文章
-
生活科技两相宜:(一)Win7使用微软SkyDrive网盘简易教程
今天得写一个Win7使用微软SkyDrive网盘的简易教程,主要是给我老婆看,顺便贴出来给大家共享一下:) 使用微软SkyDrive网盘有两个层次.一个是使用网页版,这个跟使用163或者QQ网盘 ...
-
JavaScript简易教程(转)
原文:http://www.cnblogs.com/yanhaijing/p/3685304.html 这是我所知道的最完整最简洁的JavaScript基础教程. 这篇文章带你尽快走进JavaScri ...
-
Emacs简易教程
Emacs简易教程阅读: 命令: $emacs 进入之后,输入: C-h t 这里,C-h表示按住[Ctrl]键的同时按h ####### 20090620 *退出: 输入“C-x C-c” *撤销: ...
-
文件上传利器SWFUpload入门简易教程
凡做过网站开发的都应该知道表单file的确鸡肋. Ajax解决了不刷新页面提交表单,但是却没有解决文件上传不刷新页面,当然也有其它技术让不刷新页面而提交文件,该技术主要是利用隐藏的iFrame, 较A ...
-
【转】Delphi内嵌ASM简易教程
Delphi内嵌ASM简易教程 作者:heiying2006-03-19 18:33分类:默认分类标签: 前言 Delphi作为一个快速高效的开发平台,使用的人越来越多,但熟悉在Delphi代码中嵌入 ...
-
Ant 简易教程
转载:http://www.cnblogs.com/jingmoxukong/p/4433945.html Ant 简易教程 Apache Ant,是一个将软件编译.测试.部署等步骤联系在一起加以自动 ...
-
Intellj IDEA 简易教程
Intellj IDEA 简易教程 目录 JDK 安装测试 IDEA 安装测试 调试 单元测试 重构 Git Android 其他 参考资料 Java开发IDE(Integrated Developm ...
-
MetaProducts Offline Explorer使用简易教程
MetaProducts Offline Explorer使用简易教程 by windtrace 20170419 最近想下载一个网站上的内容打包成chm文件,以便离线浏览,webzip太长时间不更 ...
-
Zabbix实战-简易教程系列
一.基础篇(安装和接入) Zabbix实战-简易教程--总流程 Zabbix实战-简易教程--整体架构图 Zabbix实战-简易教程--DB安装和表分区 Zabbix实战-简易教程--Server端 ...
随机推荐
-
团队项目——站立会议DAY6
团队项目--站立会议 DAY6 团队成员介绍(5人):张靖颜.何玥.钟灵毓秀.赵莹.王梓萱 今日(2016/5/13),站立会议已进行了一周时间,大家将这一周所遇到的问题和 ...
-
MemSQL分布式架构介绍(二)
接上次的MemSQL分布式架构介绍(一),原文在这里:http://docs.memsql.com/latest/concepts/distributed_architecture/ 首先上张图,是我 ...
-
codeforces 471B. MUH and Important Things 解题报告
题目链接:http://codeforces.com/problemset/problem/471/B 题目意思:有 n 个 tasks,编号依次为 1 - n,每个 task 都有一定的难度值来评估 ...
-
转:装完Centos7提示Initial setup of CentOS Linux 7 (core)
在用U盘装完CentOS后,重新开机启动后显示: Initial setup of CentOS Linux 7 (core) 1) [x] Creat user 2) [!] License inf ...
-
Ogre碰撞检测
转自:http://blog.csdn.net/weiqubo/article/details/7108363 Ogre采用树桩管理场景中的各种"元素"(摄像机.灯光.物体等),所 ...
-
封装Log工具类
public class LogUtil { public static final int VERBOSE = 1; public static final int DEBUG = 2; publi ...
-
Unit Of Work-工作单元
Unit Of Work-工作单元 阅读目录: 概念中的理解 代码中的实现 后记 掀起了你的盖头来,让我看你的眼睛,你的眼睛明又亮呀,好像那水波一模样:掀起了你的盖头来,让我看你的脸儿,看看你的脸儿红 ...
-
appium desktop 1.7 的swipe功能不能用,重写。
rt // @Override public void swipe(int startx,int starty,int endx,int endy,int ms){ Duration duration ...
-
ubuntu系统默认源更改为阿里源
from:http://blog.csdn.net/minicto/article/details/62240020 ubuntu系统默认源更改为阿里源 ubuntu默认使用的国外的源,在更新的时候会 ...
-
c#day01
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace test ...