Python-argparse模块

argparse 模块

什么是argparse?

argparse ——命令行选项、参数和子命令解释器
argparse 模块可以让人轻松编写用户友好的命令行接口。程序定义它需要的参数,然后 argparse 将弄清如何从 sys.argv 解析出那些参数。argparse 模块还会自动生成帮助和使用手册,并在用户给程序传入无效参数时报出错误信息。


一个可执行文件或者脚本都可以接受参数

$ ls -l /etc
/etc 是位置参数
-l 是短选项

那么如何将参数传递给程序呢?
让我们先来看看参数的分类。


参数分类

参数分为:

  • 位置参数,参数放在那里,就要对应一个参数位置。例如 /etc 就是对应一个参数位置
  • 选项参数,必须通过前面是 - 的短选项或者的长选项,然后后面的才算该选项的参数,当然选项后面也可以没有参数

上例中, /etc 对应的是位置参数,-l 是选项参数


基本解析

一下代码是一个python程序,它获取一个整数列表并计算总和或者最大值:

import argparse

parser = argparse.ArgumentParser(description='Process some integers.')
parser.add_argument('integers', metavar='N', type=int, nargs='+',
                    help='an integer for the accumulator')
parser.add_argument('--sum', dest='accumulate', action='store_const',
                    const=sum, default=max,
                    help='sum the integers (default: find the max)')

args = parser.parse_args()
print(args.accumulate(args.integers))

假设上面的 Python 代码保存在名为 prog.py 的文件中,它可以在命令行运行并提供有用的帮助消息:

$ python prog.py -h
usage: prog.py [-h] [--sum] N [N ...]

Process some integers.

positional arguments:
 N           an integer for the accumulator

optional arguments:
 -h, --help  show this help message and exit
 --sum       sum the integers (default: find the max)

当使用适当的参数运行时,它会输出命令行传入整数的总和或者最大值:

$ python prog.py 1 2 3 4
4

$ python prog.py 1 2 3 4 --sum
10

如果传入无效参数,则会报出错误:

$ python prog.py a b c
usage: prog.py [-h] [--sum] N [N ...]
prog.py: error: argument N: invalid int value: 'a'

上例代码是如何实现创建及解析参数?


创建部分
第一步,创建一个解释器

使用 argparse 的第一步是创建一个 ArgumentParser 对象:

>>> parser = argparse.ArgumentParser(description='Process some integers.')

ArgumentParser 对象包含将命令行解析成 Python 数据类型所需的全部信息。

第二步,添加参数

给一个 ArgumentParser 添加程序参数信息是通过调用 add_argument() 方法完成的。通常,这些调用指定 ArgumentParser 如何获取命令行字符串并将其转换为对象。这些信息在 parse_args() 调用时被存储和使用。例如:

>>> parser.add_argument('integers', metavar='N', type=int, nargs='+',
...                     help='an integer for the accumulator')
>>> parser.add_argument('--sum', dest='accumulate', action='store_const',
...                     const=sum, default=max,
...                     help='sum the integers (default: find the max)')

稍后,调用 parse_args() 将返回一个具有 integers 和 accumulate 两个属性的对象。integers 属性将是一个包含一个或多个整数的列表,而 accumulate 属性当命令行中指定了 --sum 参数时将是 sum() 函数,否则则是 max() 函数。


解析参数部分

ArgumentParser 通过 parse_args() 方法解析参数。它将检查命令行,把每个参数转换为适当的类型然后调用相应的操作。在大多数情况下,这意味着一个简单的 Namespace 对象将从命令行参数中解析出的属性构建:

>>> parser.parse_args(['--sum', '7', '-1', '42'])
Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42])

在脚本中,通常 parse_args() 会被不带参数调用,而 ArgumentParser 将自动从 sys.argv 中确定命令行参数。


解析器(ArgumentParser 对象)的参数

参数名称(常用)说明
prog程序的名字,缺省使用 sys.argv[0] 的 basename
add_help自动为解析器增加 -h 和 --help 选项,默认为 True
description为程序功能添加描述
add_help为解析器添加一个-h/–help选项(默认值:True)
usage描述程序用途的字符串(默认值:从添加到解析器的参数生成)

例如:

parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list directory contents')
$ python test.py --help

list directory contents

optional arguments:
	-h, --help  show this help message and exit 
位置参数解析

ls 基本功能应该解决目录内容的打印。
打印的时候应该指定目录路径,需要位置参数。

import argparse
#获取一个参数解析器
parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list directory contents')
parser.add_argument('path')

args = parser.parse_args()#分析参数
parser.print_help()#打印帮助

#运行结果,出现了错误,提示需要输入path对应的位置参数
usage: ls [-h] path
ls: error: the following arguments are required: path

程序定义为:
ls [-h] path
-h 为帮助选项,可有可无
path 为位置参数,必须提供

传参

parse_args(args=None,namespace=None)
args 参数列表,一个可迭代对象。内部会把可迭代对象转换成list。如果为 None 则使用命令行传入参数,非None则使用args参数的可迭代对象。

import argparse
#获取一个参数解析器
parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list directory contents')
parser.add_argument('path')#位置参数

args = parser.parse_args(('/etc',))#分析参数,同时传入可迭代的参数
print(args,args.path)#打印名词空间中收集的参数
parser.print_help()#打印帮助

#运行结果
Namespace(path='/etc') /etc
usage: ls [-h] path

list directory contents

positional arguments:
  path

optional arguments:
  -h, --help  show this help message and exit

Namesapce(path=’/etc’) 里面的 path 参数存储在了一个 Namespace 对象内的属性上,可以通过Namespace 对象属性来访问,例如 args.path


非必须位置参数

上面的代码必须输入位置参数,否则会报错。

usage: ls [-h] path
ls: error: the following arguments are required: path

但是有时候,ls 命令不输入任何路径的话就表示列出当前目录的文件列表。

import argparse
#获取一个参数解析器
parser = argparse.ArgumentParser(prog='ls', add_help=True, description='list directory contents')
parser.add_argument('path', nargs='?', default='.', help='path help')#位置参数

args = parser.parse_args()#分析参数,同时传入可迭代的参数
print(args,args.path)#打印名词空间中收集的参数
parser.print_help()#打印帮助

#运行结果
Namespace(path='.') .
usage: ls [-h] [path]

list directory contents

positional arguments:
  path        path help

optional arguments:
  -h, --help  show this help message and exit

可以看出 path 也变成可选的位置参,没有提供就使用默认值.点号表示当前路径。

  • help 表示帮助文档中这个参数的描述
  • nargs 表示这个参数接收结果参数
    • ? 表示可有可无
    • + 表示至少一个
    • * 可以任意个
    • 数字表示必须是指定数目个
  • default 表示如果不提供该参数,就使用这个值。一般和 ?、 * 配合,因为他们都可以不提供位置参数,不提供就用缺省值

add_argument() 方法

ArgumentParser.add_argument(name or flags…[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
定义单个的命令行参数应当如何解析。每个形参都在下面有它自己更多的描述,如下表:

参数名称(常用)说明
name or flags一个命名或者一个选项字符串的列表,例如 foo 或 -f,–foo
action当参数在命令行中出现时使用的动作基本类型
nargs命令行参数应当消耗的数目
const被一些action 和 nargs 选择所需求的常数
default当参数为在命令行中出现时使用的值
dest被添加到 parse_args() 所返回对象上的属性名

name or flags

add_argument() 方法必须知道它是否是一个选项,例如 -f 或 -foo ,或是一个位置参数,例如一组文件名。第一个传递给 add_argument() 的参数必须是一系列 flags 或者是一个简单的参数名。例如,选项可以被这样创建:

parser.add_argument('-f','--foo')

而位置参数可以这样创建:

parser.add_argument('bar')

当 parse_args() 被调用,选项会以 - 前缀识别,剩下的参数则会被假定为位置参数:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo')
>>> parser.add_argument('bar')
>>> parser.parse_args(['BAR'])
Namespace(bar='BAR', foo=None)
>>> parser.parse_args(['BAR', '--foo', 'FOO'])
Namespace(bar='BAR', foo='FOO')
>>> parser.parse_args(['--foo', 'FOO'])
usage: PROG [-h] [-f FOO] bar
PROG: error: the following arguments are required: bar

action

ArgumentParser 对象将命令行参数与动作相关联。这些动作可以做与他们相关联的命令行参数的任何事,尽管大多数动作只是简单的向 parse_args() 返回的对象上添加属性。 action 命名参数指定了这个命令行参数应当如何处理。供应的动作有:

  • ‘store’ -存储参数的值。这是默认的动作。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args('--foo 1'.split())
Namespace(foo='1')
  • ‘store_true’ and ‘store_const’ -这些是 'store_const' 分别用作存储 True 和 False 值的特殊用例。另外,他们的默认值分别为 False 和 True 。例如:
>>> 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 命名参数指定的值追加到列表中。(注意 const 命名参数默认为 None。)``'append_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)
  • ‘help’ - 打印所有当前解析器中的选项和参数的完整帮助信息,然后退出。默认情况下,一个 help 动作会被自动加入解析器。关于输出是如何创建的,参与 ArgumentParser。
  • ‘version’ - 期望有一个 version= 命名参数在 add_argument() 调用中,并打印版本信息并在调用后退出:
>>> 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

nargs

ArtgumentParser 对象通常关联一个单独的命令行参数到一个单独的被执行的动作。nargs 命名参数关联不同数目的命令行参数到单一动作。支持的值有:
*N (一个整数) 。命令行中的 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'])

注意 nargs = 1 会产生一个单元素列表。这和默认的元素本身是不同的。

  • '?' 如果可能的话,会从命令行中消耗一个参数,并产生一个单一项。如果当前没有命令行参数,则会产生 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('infile', nargs='?', type=argparse.FileType('r'),
...                     default=sys.stdin)
>>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'),
...                     default=sys.stdout)
>>> parser.parse_args(['input.txt', 'output.txt'])
Namespace(infile=<_io.TextIOWrapper name='input.txt' encoding='UTF-8'>,
          outfile=<_io.TextIOWrapper name='output.txt' encoding='UTF-8'>)
>>> parser.parse_args([])
Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>,
          outfile=<_io.TextIOWrapper name='<stdout>' encoding='UTF-8'>)
  • '*'所有当前命令行参数被聚集到一个列表中。注意通过 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

如果不提供 nargs 命名参数,则消耗参数的数目将被 action 决定。通常这意味着单一项目(非列表)消耗单一命令行参数。


const

add_argument() 的'const' 参数用于保存不从命令行中读取但被各种 ArgumentParser 动作需求的常数值。最常用的两例为:

  • 当 add_argument() 通过 action='store_const'action='append_const 调用时。这些动作将 const值添加到 parse_args() 返回的对象的属性中。
  • 当 add_argument() 通过选项(例如-f--foo)调用并且 nargs='?'时。这会创建一个可以跟随零个或一个命令行参数的选项。当解析命令行时,如果选项后没有参数,则将用 const代替。

对 ‘store_const’ 和 ‘append_const’ 动作, const 命名参数必须给出。对其他动作,默认为 None。


default

所有选项和一些位置参数可能在命令行中被忽略(未出现)。
add_argument() 的命名参数default,默认值为 None,指定了在命令行参数未出现时应当使用的值。对于选项, default 值在选项未在命令行中出现时使用:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args(['--foo', '2'])
Namespace(foo='2')
>>> parser.parse_args([])
Namespace(foo=42)

对于 nargs 等于 ?*的位置参数, default 值在没有命令行参数出现时使用。

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', nargs='?', default=42)
>>> parser.parse_args(['a'])
Namespace(foo='a')
>>> parser.parse_args([])
Namespace(foo=42)

dest

大多数ArgumentParser动作都会添加一些值作为 parse_args() 返回的对象的属性。此属性的名称由 add_argument() 的 dest关键字参数决定。

对于位置参数操作, dest通常作为第一个提供到add_argument() 的参数,例如:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
>>> parser.parse_args(['XXX'])
Namespace(bar='XXX')

对于可选参数操作,dest的值通常从选项字符串推断。ArgumentParser通过获取第一个长选项字符串并去掉初始字符串'--' 来生成dest的值。如果没有提供长选项字符串,dest将通过从第一个短选项字符串中,删除初始字符'-' 后派生。任何内部字符'-'都将转换为字符'_',以确保字符串是有效的属性名。下面的例子说明了这种行为:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-f', '--foo-bar', '--foo')
>>> parser.add_argument('-x', '-y')
>>> parser.parse_args('-f 1 -x 2'.split())
Namespace(foo_bar='1', x='2')
>>> parser.parse_args('--foo 1 -y 2'.split())
Namespace(foo_bar='1', x='2')

dest 允许提供自定义的属性名:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', dest='bar')
>>> parser.parse_args('--foo XXX'.split())
Namespace(bar='XXX')

以上…

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值