Python-argparse的使用

argparse为Python的标准库,可以用于轻松编写用户友好的命令行界面。该程序定义它需要的参数,而argparse将找出如何从sys.argv中解析这些参数。argparse还将自动生成帮助和使用消息,并在用户给程序无效参数时发出错误

示例

下面我们来使用argparse模块来定义一些命令的使用,创建一个名为exp.py文件,代码如下:

import json
import argparse

def lists():
    """
    获取列表信息
    """
    d = [i for i in range(10)]
    return json.dumps(d)
    
    
def info(name):
    """
    获取指定名称的信息
    :param name: 名称
    """
    d = {"name": name, "ip": "192.168.0.88"}
    return json.dumps(d)
    
    
if __name__ == "__main__":
    parse = argparse.ArgumentParser()
    parse.add_argument("-l", "--list", help="获取列表信息", action="store_true")
    parse.add_argument("-i", "--info", help="获取指定名称的信息")
    
    data = vars(parse.parse_args())
    if data["list"]:
        print(lists())
    elif data["info"]:
        print(info(data["info"]))
    else:
        parse.print_help()

我们来使用一下该模块有哪些命令可以使用:

root@ubuntu:~# python3 exp.py -h
usage: exp.py [-h] [-l] [-i INFO]

optional arguments:
  -h, --help            show this help message and exit
  -l, --list            获取列表信息
  -i INFO, --info INFO  获取指定名称的信息

观察返回信息可以知道,我们可以使用-l-i,以及默认的-h命令。结合代码可以知道,-i-l命令是通过代码add_argument()方法进行添加的。下面,我们来使用一下它们:

root@ubuntu:~# python3 exp.py -l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

root@ubuntu:~# python3 exp.py -i linux
{"name": "linux", "ip": "192.168.0.88"}

ArgumentParser对象

argparse模块中最核心的部分就是ArgumentParser,下面来介绍一下ArgumentParser类中所有参数的使用:

prog

程序名称。将上面exp.py模块中对ArgumentParser类中创建对象的代码修改如下:

parse = argparse.ArgumentParser(prog="测试prog")

下面我们再来看一下exp.py中帮助信息的变化:

root@ubuntu:~# python3 exp.py -h
usage: 测试prog [-h] [-l] [-i INFO]

optional arguments:
...

prog参数还有一个作用,可以使用%(prog)s格式符来定义帮助信息,如下:

parse.add_argument("-i", "--info", help="%(prog)s程序获取指定名称的信息")
...

root@ubuntu:~# python3 exp.py -h
usage: 测试prog [-h] [-l] [-i INFO]

optional arguments:
  -h, --help            show this help message and exit
  -l, --list            获取列表信息
  -i INFO, --info INFO  测试prog程序获取指定名称的信息

usage

说明中的usage说明。将上面exp.py模块中对ArgumentParser类中创建对象的代码修改如下:

parse = argparse.ArgumentParser(prog="测试prog", usage="use说明")

下面我们再来看一下帮助信息的变化,如下:

root@ubuntu:~# python3 exp.py -h
usage: use说明

optional arguments:
...

description

参数help之前显示的文本。将上面exp.py模块中对ArgumentParser类中创建对象的代码修改如下:

parse = argparse.ArgumentParser(prog="测试prog", description="description说明")

下面我们再来看一下帮助信息的变化,如下:

root@ubuntu:~# python3 exp.py -h
usage: 测试prog [-h] [-l] [-i INFO]

description说明

optional arguments:
...

epilog

参数help之后显示的文本。将上面exp.py模块中对ArgumentParser类中创建对象的代码修改如下:

parse = argparse.ArgumentParser(prog="测试prog", epilog="epilog说明")

下面我们再来看一下帮助信息的变化,如下:

root@ubuntu:~# python3 exp.py -h
usage: 测试prog [-h] [-l] [-i INFO]

optional arguments:
...

epilog说明

parents

添加父ArgumentParser对象。修改一下代码如下:

parent = argparse.ArgumentParser(add_help=False)
parent.add_argument("-p", "--parent", help="parent info")

parse = argparse.ArgumentParser(prog="测试prog", parents=[parent])

下面我们再来看一下帮助信息的变化,如下:

root@ubuntu:~# python3 exp.py -h
usage: 测试prog [-h] [-p PARENT] [-l] [-i INFO]

optional arguments:
  -h, --help            show this help message and exit
  -p PARENT, --parent PARENT
                        parent info
  -l, --list            获取列表信息
  -i INFO, --info INFO  测试prog程序获取指定名称的信息

值得注意的是,添加父ArgumentParser对象时,父对象必须带上add_help参数,并且将其设置为False,否则ArgumentParser将看到两个-h/--help选项,将会引发错误

formatter_class

ArgumentParser对象允许通过指定备用格式化类来自定义帮助格式。目前,有4个这样的类:

  • argparse.RawDescriptionHelpFormatter
  • argparse.RawTextHelpFormatter
  • argparse.ArgumentDefaultHelpFormatter
  • argparse.MetavarTypeHelpFormatter

下面对argparse.RawDescriptionHelpFormatter使用进行举例,请看下面栗子:

parse = argparse.ArgumentParser(prog="测试prog", description="""
desc-多行文本1
desc-多行文本2
desc-多行文本3
""", epilog="""
epilog-多行文本1
epilog-多行文本2
epilog-多行文本3
""")

未设置formatter_class参数时,帮助文档是这样显示的:

root@ubuntu:~# python3 exp.py -h
usage: 测试prog [-h] [-l] [-i INFO]

desc-多行文本1 desc-多行文本2 desc-多行文本3

optional arguments:
...

epilog-多行文本1 epilog-多行文本2 epilog-多行文本3

formatter_class设置为argparse.RawDescriptionHelpFormatter,帮助文档是这样显示的:

root@ubuntu:~# python3 exp.py -h
usage: 测试prog [-h] [-l] [-i INFO]

    desc-多行文本1
    desc-多行文本2
    desc-多行文本3
    
optional arguments:
...

    epilog-多行文本1
    epilog-多行文本2
    epilog-多行文本3
    

prefix_chars

命令行选项前缀。大多数情况下,命令行前缀都是以-符号开头的,例如-h/--help。如果你想使用其他的前缀作为命令行选项前缀,你可以设置此选项,如下:

parse = argparse.ArgumentParser(prog='测试prog', prefix_chars='-+')
parse.add_argument("+p", "++person", help="测试prefix_chars")

此时,我们再来看一下帮助文档是怎么显示的:

root@ubuntu:~# python3 exp.py -h
usage: 测试prog [-h] [+p PERSON]

optional arguments:
  ...
  +p PERSON, ++person PERSON
                        测试prefix_chars

值得注意的是,prefix_chars你可以设置多个命令行选项前缀,如-+&,此时你可以使用-+&前缀了。prefix_chars字符串中必须包含-字符,因为argparse有一些默认的命令,仍是以默认的-符号作为前缀的!!!

fromfile_prefix_chars

有时,在处理特别长的参数列表时,将参数保存在文件中而不是在命令行输入,这样是有意义的。有如下文件:

root@ubuntu:~# cat arg_strings.txt
-f
arg_strings.txt
-n
arg_strings

我们在将代码进行修改一下,如下:

parse = argparse.ArgumentParser(prog='测试prog', fromfile_prefix_chars='@')
parse.add_argument("-f", "--file", help='测试fromfile_prefix_chars')
parse.add_argument("-n", "--name", help="测试fromfile_prefix_chars")
data = vars(parse.parse_args(['@arg_strings.txt']))
print(data)

打印结果如下:

{'file': 'arg_strings.txt', 'name': 'arg_strings'}

argument_default

为参数设置全局默认值

parse = argparse.ArgumentParser(prog='测试prog', argument_default=argparse.SUPPRESS)
parse.add_argument("-f")
parse.add_argument("m")
parse.add_argument("n")

data = vars(parse.parse_args(["-f", "123", "hh", "eee"]))
print(data)

打印结果如下:

{'f': '123', 'm': 'hh', 'n': 'eee'}

conflict_handler

ArgumentParser对象不允许两个具有相同选项字符串的操作。默认情况下,ArgumentParser如果尝试使用已在使用的选项字符串创建参数,则对象会引发异常:

>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-f', '--file', help='file info')
>>> parse.add_argument('--file', help='new file info')
>>> parse.print_help()
Traceback (most recent call last):
    ...
argparse.ArgumentError: argument --file: conflicting option string: --file

如果想要不发生报错,我们可以使用conflict_handler参数,并且传入resolve值,使相同选项的字符串覆盖任何旧参数。使用如下:

>>> parse = argparse.ArgumentParser(prog='测试prog', conflict_handler='resolve')
>>> parse.add_argument('-f', '--file', help='file info')
>>> parse.add_argument('--file', help='new file info')
>>> parse.print_help()
usage: 测试prog [-h] [-f FILE] [--file FILE]
optional arguments:
  -h, --help   show this help message and exit
  -f FILE      file info
  --file FILE  new file info

当使用parents属性时,如果父ArgumentParser与子ArgumentParser中出现相同字符串选项时,同样可以使用conflict_handler属性

add_help

默认情况下,ArgumentParser对象会自动添加一个-h/--help选项,用于显示解析器的帮助信息。如果你不想使用此选项,可以传入add_help为False即可,效果如下:

>>> parse = argparse.ArgumentParser(prog='测试prog', add_help=False)
>>> parse.add_argument('-f', '--file', help='file info')
>>> parse.add_argument('-n', '--name', help='name info')
>>> parse.print_help()
usage: 测试prog [-f FILE] [-n NAME]
optional arguments:
  -f FILE, --file FILE  file info
  -n NAME, --name NAME  name info

可以看到,将add_help属性设置为False之后,-h/--help选项没有了!当使用parents属性时,如果父ArgumentParser中的add_help属性没有设置为False,那么将会发生报错,所以add_help还是有意义的

allow_abbrev

通常,当你将参数列表传递给ArgumentParser的parse_args()方法时,它会识别长选项的缩写,使用如下:

>>> parse = argparse.ArgumentParser(prog='测试prog', allow_abbrev=False)
>>> parse.add_argument('--basketball', help='basketball')
>>> parse.parse_args(['--basket', 'haha'])
usage: 测试prog [-h] [--basketball BASKETBALL]
测试prog: error: unrecognized arguments: --basket haha


>>> parse = argparse.ArgumentParser(prog='测试prog', allow_abbrev=True)
>>> parse.add_argument('--basketball', help='basketball')
>>> parse.parse_args(['--basket', 'haha'])
Namespace(basketball='haha')

add_argument()方法

add_argument()方法是ArgumentParser对象的核心方法,用于定义如何解析单个命令行参数,每个参数下面都有自己更详细的描述,参数如下:

name_or_flags

add_argument()方法的第一个参数,必须是一系列标志或简单的参数名称。这又分为可选参数位置参数,创建一个可选参数,如下:

parse.add_argument("-f", "--file")

而位置参数可以创建如下:

parse.add_argument("bar")

举个栗子:

>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument("-f", "--file", help='file info')
>>> parse.add_argument('bar')
>>> parse.parse_args(["data"])
Namespace(bar='data', file=None)

parse_args()被调用时,可选的参数将识别以-符号的前缀,而其余的参数则被认为是位置参数!所以,上面栗子中,bar有值,file为空

action

ArgumentParser对象将命令行参数与操作相关联,这些操作可以使用与它们相关联的命令行参数执行任何操作,尽管大多数操作只是向parse_args()返回的对象添加一个属性。action关键字参数指定应该如何处理命令行参数。操作包括:

  • store: 这是存储参数的值,这是默认的操作。例如:
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument("-f")
>>> parse.parse_args("-f file".split())
Namespace(f='file')
  • store_const: 它存储const关键字参数指定的值,该store_const操作最常用于指定某种标志的可选参数。例如:
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-f', action='store_const', const='file')
>>> parse.parse_args(['-f'])
Namespace(f='file')
  • store_true或store_false: 与store_const类似,不过store_truestore_false只能指定True或者False。使用如下:
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-t', action='store_true')
>>> parse.add_argument('-f', action='store_false')
>>> parse.parse_args("-f -t".split())
Namespace(f=False, t=True)
  • append: 它存储一个列表,并将每个参数值附加到列表中,这对于允许多次指定选项很有用。使用如下:
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-f', action='append')
>>> parse.parse_args("-f file -f info".split())
Namespace(f=['file', 'info'])
>>> parse.parse_args([])
Namespace(f=None)
  • append_const: 它存储一个列表,并将const关键字参数指定的值附加到列表中。使用如下:
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-f', action='append_const', const='file')
>>> parse.parse_args(["-f"])
Namespace(f=['file'])
  • count: 计算关键字出现的次数。使用如下:
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-f', action='count')
>>> parse.parse_args(['-ffff'])
Namespace(f=4)
  • help: 这将打印当前解析器中所有选项的完整帮助信息,然后退出,默认情况下,帮助操作会自动添加到解析器中。
  • version: 这需要调用version关键字。使用如下:
>>> import argparse
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument("--version", action='version', version='%(prog)s 1.0')
>>> parse.parse_args(["--version"])
测试prog 1.0

nargs

ArgumentParser对象通常将单个命令行参数与要采取的单个操作关联起来。nargs关键字参数将不同数量的命令行参数与一个操作关联起来。

  • N: 一个数值,命令行中的N个参数将被收集到一个列表当中,并且N必须大于0,并且必须传递N个参数,否则将报错。使用如下:
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-f', nargs=2)
>>> parse.parse_args(["-f", "1", "2"])
Namespace(f=['1', '2'])
  • ?: 如果可能,将从命令行使用一个参数,并将其作为单个项生成。如果不存在命令行参数,将使用default值。值得注意的是,对于可选参数,还有一种情况,default存在但是后面没有命令行参数,那么将使用const值。使用如下:
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-f', nargs='?', const=2, default=1)
>>> parse.add_argument('test', nargs='?', default=3)
>>> parse.parse_args("haha -f hehe".split())
Namespace(f='hehe', test='haha')
>>> parse.parse_args('haha -f'.split())
Namespace(f=2, test='haha')
>>> parse.parse_args([])
Namespace(f=1, test=3)

args=?还有个用途就是可选的输入与输出文件,使用如下:

>>> import sys
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('file', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
>>> parse.parse_args(["b.py"])
Namespace(file=<open file 'b.py', mode 'r' at 0x106d40930>)
  • *: 所有的命令行参数都收集到一个列表当中。与action='append'作用差不多,使用如下:
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-f', nargs='*')
>>> parse.add_argument('bar', nargs='*')
>>> parse.parse_args('a b c -f 1 2 3'.split())
Namespace(bar=['a', 'b', 'c'], f=['1', '2', '3'])
>>> parse.parse_args([])
Namespace(bar=[], f=None)
  • +: 与*号作用相似,只不过如果没有命令行参数时,将会发生报错,使用如下:
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-f', nargs='+')
>>> parse.add_argument('bar', nargs='+')
>>> parse.parse_args('a b -f 1 2 3'.split())
Namespace(bar=['a', 'b'], f=['1', '2', '3'])
>>> parse.parse_args([])
usage: 测试prog [-h] [-f F [F ...]] bar [bar ...]
测试prog: error: too few arguments
  • argparse.REMAINDER: 把剩余的命令行参数都收集到一个列表中。使用如下:
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-f')
>>> parse.add_argument('bar')
>>> parse.add_argument('info', nargs=argparse.REMAINDER)
>>> parse.parse_args('-f 1 2 3 4 5'.split())
Namespace(bar='2', f='1', info=['3', '4', '5'])

const

常量值。它的用途在上面几个参数的使用中已经涉及到,不在阐述

default

default参数的左右也在上面有提到。对于位置参数,如果命令行中不存在命令行参数值,那么将使用default对应的值。对于可选参数,如果命令行中不存在命令行参数值,那么僵使用const对应的值,如果可选参数都未在命令行中出现,那么将使用default对应的值。使用如下:

>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('-f', default=2)
>>> parse.parse_args([])
Namespace(f=2)

default参数还有一个特殊的值,default=argparse.SUPPRESS,如果命令行参数不存在,则不会添加任何属性:

>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('--foo', default=argparse.SUPPRESS)
>>> parse.parse_args([])
Namespace()

值得注意的是,这种情况只针对可选参数有效,对于位置参数而言,如果default参数传值为argparse.SUPPRESS,那么将会发生错误!!!

type

在默认情况下,ArgumentParser对象以简单的字符串形式读取命令行参数。但是,通常命令行字符串应该被解释成另外一种类型,如floatinttype参数允许add_argument()方法允许执行任何必要的参数类型检查和转换:

>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('--foo', type=int)
>>> parse.add_argument('bar', type=float)
>>> parse.parse_args(['--foo', '1', '2'])
Namespace(bar=2.0, foo=1)

对比之前的一些栗子,你会发现,如果没有使用type参数,那么命令行中传递的参数,将全部为字符串格式!!!

为了方便使用多种类型的文件时,argparse模块提供了FileType类,它具有modebufsizeencodingerrors参数,对应着open()函数的功能,在上面已经介绍了它的使用,不再详述。另外,type参数还可以传入open来打开一个文件,如下:

>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('--foo', type=open)
>>> parse.parse_args(['--foo', 'b.py'])
Namespace(foo=<open file 'b.py', mode 'r' at 0x1011979c0>)

type还可以传入一个可执行的函数,如下:

>>> import argparse
>>> import math
>>> def is_even_number(s):
>>>     value = int(s)
>>>     if value % 2 == 1:
>>>         msg = '{}不是偶数'.format(value)
>>>         raise argparse.ArgumentTypeError(msg)
>>>     return value
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('--foo', type=is_even_number)
>>> parse.parse_args(["--foo", "2"])
Namespace(foo=2)
>>> parse.parse_args(["--foo", "1"])
usage: 测试prog [-h] [--foo FOO]
测试prog: error: argument --foo: 1不是偶数

choice

从一组受限制的值中选择一些命令行参数,可以通过容器对象作为choice关键字参数传递给add_argument()方法来处理这些问题。在解析命令之前,将检查参数值,如果参数不是可接受值之一,将显示一条错误消息:

>>> import argparse
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('bar', choices=["1", "2", "3"])
>>> parse.parse_args(["1"])
Namespace(bar='1')
>>> parse.parse_args(["4"])
usage: 测试prog [-h] {1,2,3}
测试prog: error: argument bar: invalid choice: '4' (choose from '1', '2', '3')

required

通常,argparse模块假定标识-f/--foo为可选参数,这些参数总是可以在命令行中省略。要使选项成为必须,我们可以使用required参数,并传值为True到方法add_argument()里面:

>>> import argparse
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('--foo', required=True)
>>> parse.parse_args(["--foo", "1"])
Namespace(foo='1')
>>> parse.parse_args([])
usage: 测试prog [-h] --foo FOO
测试prog: error: argument --foo is required

help

help值是一个字符串,其中包含参数的简要描述。当用户请求帮助时,这些帮助描述将与每个参数一起显示

metavar、dest

修改可选参数的名称,使用如下:

>>> import argparse
>>> parse = argparse.ArgumentParser(prog='测试prog')
>>> parse.add_argument('--foo')
>>> parse.add_argument('--bar', metavar='BBB')
>>> parse.add_argument('--test', dest='TTT')
>>> parse.add_argument('--desc', metavar='MMM', dest='DDD')
>>> parse.parse_args(["--bar", "1", "--test", "2", "--desc", "3"])
Namespace(DDD='3', TTT='2', bar='1', foo=None)
>>> parse.print_help()
usage: 测试prog [-h] [--foo FOO] [--bar BBB] [--test TTT] [--desc MMM]

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO
  --bar BBB
  --test TTT
  --desc MMM

至此,Over~~~

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值