argparse 实战

上一篇关于 argparse 是转载别人翻译的官网的文章,最近开始脚本中需要涉及到参数处理,所以试过 sys.argv,也试过 getopt,最后再来看看 argparse,还是决定花点时间弄明白 argparse,所以一边写脚本一遍学习 argparse 了

关于 python 命令行参数解析的几个工具介绍

这篇孔令贤 的文章中有介绍,我就不多赘述,直接转过来

sys.argv

最简单最直观的手动解析

import sys
def TestSys():
for arg in sys.argv[1:]:
print (arg)

getopt

getopt 模块是原来的命令行选项解析器,支持 UNIX 函数 getopt() 建立的约定。它会解析一个参数序列,如 sys.argv,并返回一个元祖序列和一个非选项参数序列。目前支持的选项语法包括短格式和长格式选项:-a, -bval, -b val, --noarg, --witharg=val, --witharg val。如果只是简单的命令行解析,getopt 还是不错的选择。一个例子如下:

try:
options, remainder = getopt.getopt(sys.argv[1:], 'o:v', ['output=', 'verbose', 'version=',])
except getopt.GetoptError as err:
print 'ERROR:', err
sys.exit(1)

argparse

argparse是 python 标准库中的模块,以前的 optparse 已经废弃。利用 argparse,可以完成对命令行的参数定义、解析以及后续的处理。之前的一篇 argparse 中已经有介绍

这边直接利用脚本进行演示

创建对象

argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=, []formatter_class=argparse.HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True)
  • prog: 默认是sys.argv[ 0 ],即程序名
  • usage: 默认是根据参数自动生成
  • description: 对程序的描述信息,在help选项信息之前打印
  • epilog: 对程序的补充信息,在help选项信息之后打印
  • parents=list(): 继承一个父argparse对象的属性,作为一个列表元素提供
  • conflict_handler: 解决选项冲突问题
  • add_help: 增加-h/–help选项,默认开启

选项

add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
  • name: 就是选项名称
  • action:
    • store: 保存选项值
    • store_const: 保存的值由const决定
    • store_true,store_false:包含选择,则返回True或者False
    • append:将值追加到一个列表,方便重复使用选项的情况
    • append_const
    • count:记录选择的次数
    • version:取决于version关键字

docopt

docopt 就比较强大了,它是根据你自己写的 help messages(文档描述),自动为你生成 parser。使用之前需要下载相应的库,这里有个界面可以试用一下 docopt 的强大,借用官方的一个例子

"""Usage: arguments_example.py [-vqrh] [FILE] ...
arguments_example.py (--left | --right) CORRECTION FILE
Process FILE and optionally apply correction to either left-hand side or
right-hand side.
Arguments:
FILE optional input file
CORRECTION correction angle, needs FILE, --left or --right to be present
Options:
-h --help
-v verbose mode
-q quiet mode
-r make report
--left use left-hand side
--right use right-hand side
"""
from docopt import docopt
if __name__ == '__main__':
arguments = docopt(__doc__)
print(arguments)

文档描述有两个部分:UsageOption.

Usage: 以一个空行结束,冒号后面的第一个单词作为程序的名称。名称后面就是参数的描述,可以包括:

- 必选参数。是全大写的单词或尖括号括起来的的单词
- 可选参数。需要注意的是,-oiv可以表示-o -i -v。可选参数的形式可以是--input=FILE or -i FILE or even -iFILE.
- 子命令。

[]表示可选参数,如my_program.py [-hvqo FILE];
( )表示必选参数,以及没有包含在[]中都作为必选参数。
|表示互斥参数
... 表示接收多个参数值,如my_program.py FILE ...

Options:可选参数的描述。
每一行以 `- or --` 开头;同一行相同可选参数以空格隔开;两个或以上的空格分隔描述;可以定义默认值([default: value]);

需要注意的是,docopt 不能完成 argparse 具有的参数值校验的功能。目前 docopt 已经被移植到了 Ruby, PHP 等语言
更多的例子可以参考[这里](https://github.com/docopt/docopt/tree/master/examples)

clize

clize 也比较强大,利用装饰器将函数转换成命令行解析器。github地址:https://github.com/epsy/clize,一个例子:

#!/usr/bin/env python
from clize import run
from sigtools.modifiers import autokwoargs
@autokwoargs
def echo(word, prefix='', suffix=''):
"""Echoes text back
word: One word or quoted string to echo back
prefix: Prepend this to each line in word
suffix: Append this to each line in word
"""
if prefix or suffix:
return '\n'.join(prefix + line + suffix
for line in word.split('\n'))
return word
if __name__ == '__main__':
run(echo)

生成的帮助文档如下:

$ ./echo.py --help
Usage: ./echo.py [OPTIONS] word
Echoes text back
Positional arguments:
word One word or quoted string to echo back
Options:
--prefix=STR Prepend this to each line in word(default: )
--suffix=STR Append this to each line in word(default: )
Other actions:
-h, --help Show the help

但个人感觉 clize 与 argparse 和 docopt 比起来,支持的功能相对还比较少,而且不容易上手(因为要熟悉相关的各种装饰器及其参数的使用),要支持高级解析功能,代码写起来比较费劲

argparse 实例脚本

更多阅读