Python命令行参数解析模块 argparse

简介

Python 中自带的argparse模块可以用于提供简洁易用的命令行参数解析。

程序内部定义了需要使用的参数,argparse 会默认自动从 sys.argv中解析出对应的参数。argparse模块会自动生成帮助信息和使用提示,同时当用户使用无效参数时,会显示错误原因。

注: Python 中还有其他两个模块可以提供相同的命令行参数解析功能:getopt(等同于 C 语言的getopt())和optparse(Python2.7以后被标记为 Deprecated,不会继续发展)。
其中,argparse是基于optparse的进一步封装,因此这两者拥有相似的使用方法。

参数类型说明

命令行参数类型可以分为以下两种:

  • 位置参数(positional argument):位置参数拥有一个具体的名字,以便让程序知道如何使用其值。比如cp SRC DEST,参数SRCDEST就是两个位置参数,其值类型为字符串。
  • 可选参数(optional argument):可选参数用于提供额外信息给到程序,让程序可以提供额外的一些操作。比如ls -als --all-a--all就是可选参数,应用程序ls接收到-a/--all参数后,就会使能显示隐藏文件功能。

命令行参数通用格式为:program [optional] positional

简单示例

下面列举一些简单的例子,力求对 argparse有一个初步的了解。更多详细的示例,请参考:Argparse Tutorial

示例1. 添加一个位置参数:square,其类型为int

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)

上述代码生成的程序使用格式为:usage: argTest.py [-h] square,因此具体使用应类似:$ python3 argTest.py 4

argparse中参数类型默认为字符串(string),可以通过type参数指定参数类型。

实例2. 添加一个可选参数:-v/--verbose:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbose", help="increase output verbosity")
args = parser.parse_args()
if args.verbose:
    print("verbosity turned on")

上述代码生成的程序使用格式为:usage: argTest.py [-h] [-v VERBOSE],可选参数-v/--verbose后面必须加上一个值(任意类型)。因此具体使用应类似:

$ python3 argTest.py -v 1
verbosity turned on
$ python3 argTest.py --verbose haha
verbosity turned on

通常程序的可选参数表现形式为布尔值类型:TrueFalse。可以通过在方法add_argument中为参数加上参数action进行指定。

实例3. 为程序添加一个位置参数:square,类型为int;同时添加一个布尔类型的可选参数:-v/--verbose:

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)

上述代码生成的程序使用格式为:usage: argTest.py [-h] [-v] square,因此具体使用应类似:

$ python3 argTest.py
usage: argTest.py [-h] [-v] square
argTest.py: error: the following arguments are required: square
$ python3 argTest.py 4
16
$ python3 argTest.py 4 --verbose
the square of 4 equals 16
$ python3 argTest.py --verbose 4
the square of 4 equals 16

action="store_true"表示当显示指定了可选参数时,其值为True,当未指定时,则为False
action="store_false"与之相反,当未指定参数时,其值为True,当显示指定参数时,其值为False

关键函数讲解

从上面的示例中我们可以看到,argparse主要涉及到3个调用:

  • argparse.ArgumentParser()ArgumentParser 是一个类,该类对象内部维护了对命令行参数解析为 Python 数据类型所必须的所有信息。
    其构造函数有如下参数可供使用:
Argument Description
prog 应用名称(默认:sys.argv[0]
usage 程序使用方法描述
description 显示在参数列表帮助信息之前的文本展示(默认:无)
epilog 显示在参数列表帮助信息之后的文本展示(默认:无)
parents 需要同时添加的一系列ArgumentParser对象
formatter_class 自定义帮助信息输出的类
prefix_chars 可选参数前缀字符(默认:‘-‘)
fromfile_prefix_chars 参数文件集前缀字符(默认:无)
argument_default 全局参数默认值(默认:无)
conflict_handler 可选参数冲突解决策略(通常不需要)
add_help 为解析器增加一个-h/--help选项(默认:True
allow_abbrev 允许长选项简短表示,只要简短表示不具备二义性(默认:True

:所有参数均为 关键字参数,需以键值对形式进行传参。

  • ArgumentParser.add_argument:定义单个命令行参数解析规则。
    每个命令行参数拥有多个详细描述,如下所示:
Argument Description
name or flags 一个名称或则参数字符串列表。e.g. foo or -f, --foo
action 对该参数的处理动作
nargs 提取的命令行参数对应的值的个数
const 如果命令行没有传入该参数,const指定该参数的默认值,在某些action与nargs类型下才起作用
default 命令行中如果缺少该参数,则使用该 default 指定的值
type 参数应转化成的类型
choices 参数允许的值
required 表明参数是否是必须的,只对可选参数有效
help 参数对应的简短描述
metavar 在使用信息中该参数对应的名称
dest parse_args()返回的对象对应的属性名称

其中:
action 有如下几个选项:

  • store:存储参数值。该行为是默认行为。
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args('--foo 1'.split())
Namespace(foo='1')
  • store_const:存储关键字参数 const 指定的值。该行为最常用于可选参数作为某些标识使用。
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
>>> parser.parse_args(['--foo'])
Namespace(foo=42)
  • store_truestore_false:该类型为store_const用于存储TrueFalse的特例。
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
>>> parser.add_argument('--bar', action='store_false')
>>> parser.add_argument('--baz', action='store_false')
>>> parser.parse_args('--foo --bar'.split())
Namespace(foo=True, bar=False, baz=True)
  • append:该选项存储一个列表,并且把每个参数值添加到列表中。对于允许一个选项指定多次的场景很有用。
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])
  • append_const:该选项存储一个列表,并且把关键字参数 const 指定的值存储进列表中。该选项的典型使用场景是把多个具备常量值的参数存储进同一个列表中。
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--str', dest='types', action='append_const', const=str)
>>> parser.add_argument('--int', dest='types', action='append_const', const=int)
>>> parser.parse_args('--str --int'.split())
Namespace(types=[<class 'str'>, <class 'int'>])
  • count:该选项统计某一关键字参数出现的次数。
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--verbose', '-v', action='count')
>>> parser.parse_args(['-vvv'])
Namespace(verbose=3)
  • version:该选择需要在 add_argument() 方法中添加关键字参数version,调用时会自动打印版本信息并自动退出。
>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--version', action='version', version='%(prog)s 2.0')
>>> parser.parse_args(['--version'])
PROG 2.0
  • help:打印完整的参数帮助信息。

nargs 有如下几个选项:

  • N(整型):指定参数后面数值个数,合并到一个列表中。
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs=2)
>>> parser.add_argument('bar', nargs=1)
>>> parser.parse_args('c --foo a b'.split())
Namespace(bar=['c'], foo=['a', 'b'])
  • ?:一个命令行参数值最多只接收一个值(单条目)。如果没有对应参数,则使用 default 指定的值。对于可选参数,有一个特例:如果只显示了参数,但没有尾随提供一个值,则使用 const 指定的值。
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='?', const='c', default='d')
>>> parser.add_argument('bar', nargs='?', default='d')
>>> parser.parse_args(['XX', '--foo', 'YY'])
Namespace(bar='XX', foo='YY')
>>> parser.parse_args(['XX', '--foo'])
Namespace(bar='XX', foo='c')
>>> parser.parse_args([])
Namespace(bar='d', foo='d')
  • *:所有显示指定的参数会聚集到一个集合中。通常来说,对多个位置参数使用nargs='*'并没有多大意义,但对于多个可选参数却是可以的。
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='*')
>>> parser.add_argument('--bar', nargs='*')
>>> parser.add_argument('baz', nargs='*')
>>> parser.parse_args('a b --foo x y --bar 1 2'.split())
Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
  • +:与*一样,将所有显示指定的参数聚集到一个列表中。另外,当一个命令行参数都没有指定时,会抛出一个错误信息。
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', nargs='+')
>>> parser.parse_args(['a', 'b'])
Namespace(foo=['a', 'b'])
>>> parser.parse_args([])
usage: PROG [-h] foo [foo ...]
PROG: error: the following arguments are required: foo
  • argparse.REMAINDER:将剩余的命令行参数聚集到一个列表中。通常用于命令行工具分发给其他命令行工具。
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo')
>>> parser.add_argument('command')
>>> parser.add_argument('args', nargs=argparse.REMAINDER)
>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')

如果nargs关键字参数未提供,则读取的参数个数由action决定。通常这意味着将读取一个命令行参数并产生一个元素(不是一个列表)。

参考

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341

推荐阅读更多精彩内容