Python学习笔记(三) Python中的命令行解析工具argparse

 

 

最近看一些开源的项目,使用命令行解析工具,针对不同的任务通过修改命令行来让程序运行起来相当方便。主要使用到的模块是Python推荐的命令行解析模块argparse,为了了解它的工作过程,我也在网上找了找一些中文的博客教程,但是感觉对于新手很不友好,后来发现原来官方教程才是最好的教程。下面分享一下学习经验:

我使用的python版本是python3.5。本文主要参考:https://docs.python.org/3.5/howto/argparse.html#id1

1、命令行

首先,说一下命令行。它在我们windows操作系统中就是cmd的那个大黑框,你可以通过不同的命令来对系统进行操作,但是windows操作系统中我们一般都使用了图形化的操作界面完成,因此对于命令行使用较少;而在linux中,使用命令行来进行操作就相当普遍了,毕竟是针对程序员设计的操作系统,采用命令行进行相关操作更加的简洁有效。

我们在使用命令行的时候,对于一个简单的查看当前目录下有哪些文件的命令-ls,可以执行以下的操作:

这是一条很有用的命令,他没有别的任何选项,默认的操作是查看当前目录下的内容。为了得到当前目录下的更详细内容信息,我们可以使用“ls -l”命令:

 

-l 这个参数,在这里就是一个可选的输入,它改变了ls命令的原有行为,显示出了更多的信息。除此之外,我们还可以使用“ls --help”或者“ls -h”来获取帮助信息:

在这里,‘-h’被称作短命令,“--help”被称作长命令,他俩的效果是一样的。你可以将上图中的“--help”替换成“-h”而得到相同的结果。

2、argparse使用

如果我们希望对我们编写的xxx.py程序,通过不同的命令来完成不同的功能的话,就需要使用argparse模块。下面我们来看看它能干什么,首先看一个几乎什么也没干的程序prog.py:

1 import argparse
2 parser = argparse.ArgumentParser()
3 parser.parse_args()

我们对这个进行运行:

图中的[1]-[4]分别是运行不同的命令给出的结果。在[1]中,我们采用了传统的方式对程序进行运行,结果我们什么输出也没得到(因为这个程序基本什么也没做)。在[2]中,我们给了这个程序一个命令“--help”,但是我们得到了一个输出——一个帮助信息。这是由于代码中使用了argparse,它自带一个help信息,也是唯一自带的,这也可以通过短命令“-h”来得到。[3]和[4]中由于没有事先定义参数信息,所以给出了错误。

3、位置参数

来看下面的一组例子:

1 import argparse
2 parser = argparse.ArgumentParser()
3 parser.add_argument("echo")
4 args = parser.parse_args()
5 print(args.echo)

在这段代码中,我们相对之前的代码,使用了add_argument和parse_arg()方法。我们对程序进行运行:

在这里,我们使用add_argument方法来指定我们的程序将接收什么样的命令行,这里将其命名为echo。而parse_arg()方法是用来从指定的操作中返回数据的,在这个例子中,返回的就是echo。你可以看到我们使用了echo这个变量,而定义的时候我们使用的是字符串。这就是argparse做的事情,将变量与字符串对应起来,我们不需要指定给定的参数存储到哪个变量中。

在之前的例子中,我们使用了命令--help,实际上,你可以编辑它,以显示更加有用的帮助信息:

1 import argparse
2 parser = argparse.ArgumentParser()
3 parser.add_argument("echo", help="echo the string you use here")
4 args = parser.parse_args()
5 print(args.echo)

这时候,我们能够得到如下的输出:

在之前的例子中,通过命令行输入的参数,都是以字符串被存储的,如果你想要将其当成数字来使用,则需要在add_argument中指定type信息,来告诉程序,你输入的是数字:

1 import argparse
2 parser = argparse.ArgumentParser()
3 parser.add_argument("square", help="display a square of a given number",
4                     type=int)
5 args = parser.parse_args()
6 print(args.square**2)

这样,你就能得到想要的输出了:

4、可选参数

在上面的例子中,参数是必须添加的,如果不添加,将造成错误:

如何做到默认时无需添加参数呢?请看下面的例子:

1 import argparse
2 parser = argparse.ArgumentParser()
3 parser.add_argument("--verbosity", help="increase output verbosity")
4 args = parser.parse_args()
5 if args.verbosity:
6     print("verbosity turned on")

注意,这个例子中verbosity前面的“--”。我们下面对这个程序进行运行:

在这个运行的样例中,可以看到,在第二次运行时,并没有指定参数,但是程序依旧运行了。这就是可选参数。在一个命令行中,如果可选参数没有被指定,那么相应的变量值就是None。因此,第二次运行时,没有执行if语句中的内容。相对于之前的位置参数,可选参数的help不同了。如果你使用了--verbosity,你必须指定某个值,任意值。

在上面的例子中,实际上对于我们有用的verbosity的值只有True或者False,因此我们可以通过加入action关键字来对上面的程序进行改写:

1 import argparse
2 parser = argparse.ArgumentParser()
3 parser.add_argument("--verbose", help="increase output verbosity",
4                     action="store_true")
5 args = parser.parse_args()
6 if args.verbose:
7     print("verbosity turned on")

我们运行代码:

注意运行的结果,我们给定action的值是“store_true”,这表明,如果我们指定了可选项--verbose,那么就将True赋值给对应的变量,如果没有则赋值为False。如果你在后面指定了值,则会报错(注意看help信息与之前有什么不同)。

短命令:

短命令的指定很简单,只需要在add_argument里面加一个短命令就可以了,注意使用的是一个横线“-”

1 import argparse
2 parser = argparse.ArgumentParser()
3 parser.add_argument("-v", "--verbose", help="increase output verbosity",
4                     action="store_true")
5 args = parser.parse_args()
6 if args.verbose:
7     print("verbosity turned on")

运行结果如下:

5、混合使用位置参数和可选参数

 1 import argparse
 2 parser = argparse.ArgumentParser()
 3 parser.add_argument("square", type=int,
 4                     help="display a square of a given number")
 5 parser.add_argument("-v", "--verbose", action="store_true",
 6                     help="increase output verbosity")
 7 args = parser.parse_args()
 8 answer = args.square**2
 9 if args.verbose:
10     print("the square of {} equals {}".format(args.square, answer))
11 else:
12     print(answer)

我们运行上面的代码可以得到输出:

以上是对argparse模块的一些简单使用的介绍。实际上,你还可以加入形如"choices = [0, 1, 2]"的命令来限制输入在0-2的整数(超出会报错)。通过指定action="count"能够对可选参数进行计数等等。更多的高级操作可以访问python官网找到document:

https://docs.python.org/3.5/howto/argparse.html#id1

posted @ 2018-04-17 20:52  NeoScofield  阅读(1383)  评论(0编辑  收藏  举报