Python Argparse 简易指南

来源:互联网 发布:星落五丈原 知乎 编辑:程序博客网 时间:2024/06/05 02:22

Argparse Tutorial

author: Tshepang Lekhonkhobe

翻译:田福顿

这份指导的目的在于简单的向大家的介绍argparse包,一个Python标准库中推荐使用的命令执行模块。这个教程是在Python3.X中运行调试完成的,会有一些使用细节与Python2.x不一致,特别是性能在python3.x中得到提升的异常处理方面。

Note
还有两个模块可以满足一样的功能,一个是getopt(等价于C语言中个的getopt()),另一个是不推荐使用的的optparse。值得注意的是argparse同样是基于optparse发展而来,所以在使用方法上两者有相似之处。

Concepts

让我们通过使用ls命令来展示一些我们将要在这份指导中学到功能类别。

$ lscpython  devguide  prog.py  pypy  rm-unused-function.patch$ ls pypyctypes_configure  demo  dotviewer  include  lib_pypy  lib-python ...$ ls -ltotal 20drwxr-xr-x 19 wena wena 4096 Feb 18 18:51 cpythondrwxr-xr-x  4 wena wena 4096 Feb  8 12:04 devguide-rwxr-xr-x  1 wena wena  535 Feb 19 00:05 prog.pydrwxr-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 --helpUsage: 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命令时,它会默认显示当前目录内容、

·如果我们想在默认情况的基础上多了解一些,我们可以多告诉ls命令一些信息。在上述的例子中,当我们想要显示不同的目录信息,我们则在-ls 命令后制定了一个路径pypy。‘pypy’在这里就代表了位置参数。这个参数如何被执行将完全依赖于参数所处的位置。这个概念和命令cp(最基本的用用法是 cp SRC DEST)更加有关系。第一个位置参数代表你想要从哪里复制,第二各参数代表你想要复制到哪里。

·现在,我们想要改变这个程序的所显示的结果。在我们的例子中。我们用显示每个文件的详细信息来替代显示文件名字。 在这个例子中,-l参数就被称为可选参数。

·例子四是一份非常有用的帮助文本片段,你当你遇到你从未使用过的程序时,你就可以通过阅读帮助文本来了解程序的用法。

基础

让我们用一个非常简单,简单到几乎没有任何实际功能的例子开始吧:

import argparseparser = argparse.ArgumentParser()parser.parse_args()

执行程序后你会看到这样的结果:

$ python prog.py$ python prog.py --helpusage: prog.py [-h]optional arguments:  -h, --help  show this help message and exit$ python prog.py --verboseusage: prog.py [-h]prog.py: error: unrecognized arguments: --verbose$ python prog.py foousage: prog.py [-h]prog.py: error: unrecognized arguments: foo

发生了什么?

·当不带可选参数运行这段代码时,没有任何显示信息。

·第二次运行时程序开始显示一些关于argparse模块的信息,我们几乎没有(对这个模块)做什么事,但是我们已经可以得到不错的帮助信息了。

·–help选项(可以被缩写成-h)使我们唯一可以不同特别定义就能得到的功能。在没有定义其他命令时,使用出–help以外的可选命令都将抛出异常。

介绍位置参数

一个例子:

import argparseparser = argparse.ArgumentParser()parser.add_argument("echo")args = parser.parse_args()print args.echo

运行这段代码:

$ python prog.pyusage: prog.py [-h] echoprog.py: error: the following arguments are required: echo$ python prog.py --helpusage: prog.py [-h] echopositional arguments:  echooptional arguments:  -h, --help  show this help message and exit$ python prog.py foofoo

发生了什么:

·我们添加了用来指定什么命令行选项可以被接受的add_argument()方法。在这个例子中,我们将其命名为‘echo’。

·现在我们的程序在调用时要求我们指定一个选项。

· parse_args() 方法实际上用来返回一些来自指定选项的数据,在这个例子中,返回的是echo。

·你不需要指定传入的值属于哪个变量,你也应当注意到变量名是匹配传入此方法的字符串参数的的,在这个例子中,则是将字符串“foo”传入“echo”

尽管help命令返回的帮助文本看起来已经足够好和完整了,但他还可以对我们更有帮助。举个例子,我们可以看echo作为位置参数,但是我们并不知道怎么用使用它。想要知道怎么使用echo我们只能靠猜和阅读源代码。现在,让我们将help变得更有用处。

import argparseparser = argparse.ArgumentParser()parser.add_argument("echo", help="echo the string you use here")args = parser.parse_args()print args.echo

这是我们得到的:

$ python prog.py -husage: prog.py [-h] echopositional arguments:  echo        echo the string you use hereoptional arguments:  -h, --help  show this help message and exit

现在,我们还可以使它更有用处。

import argparseparser = 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 4Traceback (most recent call last):  File "prog.py", line 5, in <module>    print args.square**2TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'

呀,并没有成功执行呢,这是因为argparse将一切可选参数作为string来处理,除非我们告诉argparse我们输入的是其他类型的参数。

import argparseparser = 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 416$ python prog.py fourusage: prog.py [-h] squareprog.py: error: argument square: invalid int value: 'four'

这次成功啦,现在的代码能提示我们非法输入了

介绍可选参数

目前为止,我们已经展示了位置参数,现在让我们看下怎么添加可选参数吧

import argparseparser = 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 1verbosity turned on$ python prog.py$ python prog.py --helpusage: prog.py [-h] [--verbosity VERBOSITY]optional arguments:  -h, --help            show this help message and exit  --verbosity VERBOSITY                        increase output verbosity$ python prog.py --verbosityusage: prog.py [-h] [--verbosity VERBOSITY]prog.py: error: argument --verbosity: expected one argument

发生了什么:

·当我们使用–verbosity这个可选参数时,程序会打印一些信息,当没使用时则不会打印

·为了证明可选参是真的是可选的,这段程序在没有指定–verbosity 时运行也不会报错。注意它的默认情况,如果可选参数没有被使用,他的相关变量,在本例中就是 args.verbosity ,会被赋予一个None,这也就是为什么在使用 if args.verbosity: 时会返回False。

·当使用–verbosity 选项时,必须指定一个值,什么值都可以。

上边例子为 –verbosity接受了一个数字作为值作,但是,再我们简单的程序中,只有两个值是有用,True 或者 False.让我们根据这点修改下代码吧。

import argparseparser = 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 --verboseverbosity turned on$ python prog.py --verbose 1usage: prog.py [-h] [--verbose]prog.py: error: unrecognized arguments: 1$ python prog.py --helpusage: prog.py [-h] [--verbose]optional arguments:  -h, --help  show this help message and exit  --verbose   increase output verbosity

发生了什么:

现在可选参数更像是一个标志,而不需要值的变量。我们新建了一个参数来与前面的例子作区分。注意,我们现在指定了一个关键字,‘action’,然后给他了一个值‘”store_true”’,这个意味着如果可选参数被指定了一个值则分配一个’True’值到args.verbose。没有的话则分配False。

缩写版可选参数

如果你对命令行很熟悉的话,你会发现我们到现在还没有提到过可选命令的缩写版本这个话题,这也很简单

import argparseparser = 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 -vverbosity turned on$ python prog.py --helpusage: prog.py [-h] [-v]optional arguments:  -h, --help     show this help message and exit  -v, --verbose  increase output verbosity

注意,新功能也在帮助文本中反应出来了哦.

组合使用位置参数和可选参数

我们的程序变得更加复杂了:

import argparseparser = 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**2if args.verbose:    print "the square of {} equals {}".format(args.square, answer)else:    print answer

这是结果:

$ python prog.pyusage: prog.py [-h] [-v] squareprog.py: error: the following arguments are required: square$ python prog.py 416$ python prog.py 4 --verbosethe square of 4 equals 16$ python prog.py --verbose 4the square of 4 equals 16

不如我们给这段程序加上多个verbosity,并真正的使用它们。

import argparseparser = 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**2if 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 416$ python prog.py 4 -vusage: prog.py [-h] [-v VERBOSITY] squareprog.py: error: argument -v/--verbosity: expected one argument$ python prog.py 4 -v 14^2 == 16$ python prog.py 4 -v 2the square of 4 equals 16$ python prog.py 4 -v 316

除了最后一个,一切都运行得很好。我们程序出现了bug,现在让我们通过限制verbosity option可以接受的值,来修改这个bug。

import argparseparser = 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**2if 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 3usage: prog.py [-h] [-v {0,1,2}] squareprog.py: error: argument -v/--verbosity: invalid choice: 3 (choose from 0, 1, 2)$ python prog.py 4 -husage: prog.py [-h] [-v {0,1,2}] squarepositional arguments:  square                display a square of a given numberoptional arguments:  -h, --help            show this help message and exit  -v {0,1,2}, --verbosity {0,1,2}                        increase output verbosity

现在我们的修改同时也反映在了帮助文本里面。.

让我们通过不同的途径来调戏verbosity吧,这也符合了CPython的可执行文件处理自己的verbosity方式

import argparseparser = 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**2if 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 416$ python prog.py 4 -v4^2 == 16$ python prog.py 4 -vvthe square of 4 equals 16$ python prog.py 4 --verbosity --verbositythe square of 4 equals 16$ python prog.py 4 -v 1usage: prog.py [-h] [-v] squareprog.py: error: unrecognized arguments: 1$ python prog.py 4 -husage: prog.py [-h] [-v] squarepositional arguments:  square           display a square of a given numberoptional arguments:  -h, --help       show this help message and exit  -v, --verbosity  increase output verbosity$ python prog.py 4 -vvv16

现在出现了一个和action=”store_true”类似标志,它和“store_true”的用法类似,现在,让我们句个例子来说明‘count’的功能。像“store_true”一样,如果你没有你指定-v,这个信号将会默认为None。不过help并没有更新我们的新功能用法,没关系我们可以手动添加~

import argparseparser = 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 -vvvthe square of 4 equals 16$ python prog.py 4 -vvvvthe square of 4 equals 16$ python prog.py 4Traceback (most recent call last):  File "prog.py", line 11, in <module>    if args.verbosity >= 2:TypeError: unorderable types: NoneType() >= int()

呀,又出现了一个bug.

来解决吧:

import argparseparser = 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**2if 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,我们将他用来避免在和int值比较时出现的错误。在默认情况系如果可选参数没有给定一个值,会返回None,None不能和int进行比较,所以会出现 TypeError。 而现在,使用了default后,则会返回default的值。

$ python prog.py 416

我们目前所学习的知识,都还只是一些皮毛,argparse 的模块的功能是非常强大的,在这份指导结束之前,还有一些进阶的用法待学习。

进阶学习

到目前为止,我们已经学习argparse中的两种方法,现在是时候学习第三种噜。第三种是 add_mutually_exclusive_group()。它允许我们制定不能与其他可选参数共同使用的可选参数。现在我们来写改一下我们的程序,让我们能够更加直观的理解新功能。我们会介绍 –quite这个这个不能与 –verbose一同执行可选参数。

import argparseparser = 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.yif args.quiet:    print answerelif args.verbose:    print "{} to the power {} equals {}".format(args.x, args.y, answer)else:    print "{}^{} == {}".format(args.x, args.y, answer)Our program is now simpler, and we’ve lost some functionality for the sake of demonstration. Anyways, here’s the output:$ python prog.py 4 24^2 == 16$ python prog.py 4 2 -q16$ python prog.py 4 2 -v4 to the power 2 equals 16$ python prog.py 4 2 -vqusage: prog.py [-h] [-v | -q] x yprog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose$ python prog.py 4 2 -v --quietusage: prog.py [-h] [-v | -q] x yprog.py: error: argument -q/--quiet: not allowed with argument -v/--verbose

上边那段代码应该不难看懂吧,我把最后的输出打印了出来这样你就可以比较清楚地明白你输出了什么。比如:混合了长参数和缩写参数的命令结构

在我们总结之前,你可能想要告诉你的读者你的程序主要功能是什么,万一他们不知道呢?

import argparseparser = 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.yif args.quiet:    print answerelif args.verbose:    print "{} to the power {} equals {}".format(args.x, args.y, answer)else:    print "{}^{} == {}".format(args.x, args.y, answer)Note that slight difference in the usage text. Note the [-v | -q], which tells us that we can either use -v or -q, but not both at the same time:$ python prog.py --helpusage: prog.py [-h] [-v | -q] x ycalculate X to the power of Ypositional arguments:  x              the base  y              the exponentoptional arguments:  -h, --help     show this help message and exit  -v, --verbose  -q, --quiet

结论

argparse包的功能远比我们今天介绍了的来得多。它的说明文档也非常详细,而且有很多的例子来帮助理解。当你读完这个指南,你应当能轻松的消化掉里面的知识而且没有不堪重负的感觉。

0 0
原创粉丝点击