Python标准库【argparse】命令行解析


参考:argparse模块官方文档


1 argparse模块

1.1 简介

argparse是标准库中用于命令行解析的模块。
在程序中定义好需要的参数后,argparse会从sys.argv解析它们。
argparse还可以自动生成帮助和用法消息文本,发出错误提示。

getopt模块也可以完成相同的任务。
argparse基于被弃置的optparse模块(自3.2版本)实现,用法很相似。

1.2 解析器和使用方法

argparse模块对命令行的解析是围绕参数解析器argparse.ArgumentParser的实例建立的。
argparse.ArgumentParser的实例有两个常用的方法:add_argument()parse_args()
其中add_argument用于将参数及其说明关联到解析器。
parse_args运行解析器,然后把提取到的数据放入对象。

使用argparse模块的基本步骤:

import argparse
# 实例化解析器
parser = argparse.ArgumentParser(**kwargs)
# 将参数关联到解析器
parser.add_argument(*args, **kwargs)
# 从sys.argv提取参数,转换为命名空间的属性
args = parser.parse_args(args=None, namespace=None)

parse_args接收的参数args默认是从sys.argv取的,而sys.argv的值就是外部传入的字符串列表。后续的一些测试会直接将列表传给parse_args。

# test.py
import sys
import argparse
print(sys.argv)
>>> python test.py abc -host 0.0.0.0 -port 80 xyz
['test.py', 'abc', '-host', '0.0.0.0', '-port', '80', 'xyz']

2 ArgumentParser的初始化参数

创建ArgumentParser实例的可选参数如下:

parser = 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, allow_abbrev=True, exit_on_error=True
)

注意 ArgumentParser初始化的所需参数都是关键字参数。

  • prog
    表示程序的名称,用于在help信息中展示。
    默认值是os.path.basename(sys.argv[0])

    prog的值可以在后续写帮助信息时通过%(prog)s格式引用。

  • usage
    描述程序用途,会在帮助信息中显示。
    帮助信息第一行默认显示格式是usage: 程序名称 [可用选项]
    可以通过usage参数改变这里显示的内容。

  • description
    在usage之后,在参数帮助信息之前显示的文本。一般简要描述这个程序会做什么、和如何做的。
    description文本默认情况下会换行,可以由参数formatter_class控制不换行。

  • epilog
    在参数帮助信息之后显示的额外的对程序的描述。
    epilog文本默认情况下会换行,可以由参数formatter_class控制不换行。

  • parents
    ArgumentParser对象列表。
    有时多个解析器会使用同一系列的参数,可以把这些参数先定义给一个父解析器,然后在其它解析器使用parents指定这个父解析器。

    父解析器需要指定add_help=False,否则解析器发现两个帮助选项就会产生一个错误。所以父解析器对帮助信息做的修改不会出现在子解析器上。
    子解析器创建之后再改变父解析器,改变不会在子解析器上出现。

  • formatter_class
    用于自定义帮助文档输出格式的类。
    目前可选的类有四种:
    argparse.RawDescriptionHelpFormatter,不会将description和epilog内容自动换行;
    argparse.RawTextHelpFormatter,保留编辑帮助信息时写的所有空白符。
    argparse.ArgumentDefaultsHelpFormatter,自动把参数的默认值信息加到帮助信息中。
    argparse.MetavarTypeHelpFormatter,在参数说明中使用参数的type当做参数的显示名。

  • prefix_chars
    可选参数的前缀字符集,默认值是"-"

  • fromfile_prefix_chars
    参数列表很长时,可以写在一个文件中,通过命令行传给程序。
    fromfile_prefix_chars表示需要从文件中读取其他参数时,用于标识文件名的前缀字符集合。
    以给定字符开头的参数都会被当做文件处理,并被它们包含的参数替换。

  • argument_default
    参数的全局默认值,默认是None。

  • conflict_handler
    相同的选项字符串被重复定义时,解析器会产生一个异常。
    如果想重写旧的参数选项,使参数conflict_handler='resolve'即可。

  • add_help
    是否为解析器添加-h/--help帮助选项,默认True。

    如果“-”符号没有被参数prefix_chars指定的字符串包含,就使用prefix_chars的第一个字符当做帮助选项的前缀。

  • allow_abbrev
    如果缩写是无歧义的,是否允许缩写长选项,默认True。
    这种情况下,长选项使用其前缀也能够成功传参。
    如果长选项和其前缀选项是不同的定义,需要把allow_abbrev定为False。

  • exit_on_error
    parse_args()接收到错误的参数时,默认情况下解析器会打印一个错误提示并退出。
    如果想要手动捕获错误,可以把exit_on_error设为False。


3 add_argument()方法

add_argument()用于定义单个命令行参数如何解析。方法参数如下:

ArgumentParser.add_argument(
    name or flags [, action][, nargs][, const]
    [, default][, type][, choices][, required]
    [, help][, metavar][, dest][, deprecated]
)
  • name or flags
    一个名称(name)或者多个选项字符串(flags)。
    名称表示位置参数,命令行运行时处于该位置的字符串会当做参数的值。
    多个选项字符串表示选项参数,命令行运行时出现这个选项时,之后的一个字符串会当做参数的值。

    # 添加位置参数
    parser.add_argument('bar')
    parser.add_argument('coco')
    # 添加选项参数foo
    parser.add_argument('-f','--foo')
    # 解析命令行并打印
    args = parser.parse_args('1 -f abc xyz'.split())
    print(args)
    
    # 打印的结果,
    Namespace(bar='1', coco='xyz', foo='abc')
    

    parse_args()会先按前缀识别选项参数,然后剩下的参数被当做位置参数按顺序依次赋值。
    选项参数不受传参的顺序影响。

  • action
    当参数在命令行中出现时使用的动作。

    • action='store',默认值,直接存储参数的值;
    • action='store_const',存储由const参数指定的值;外部不传这个参数则存None。
    • action='store_true',存储True值,外部不传这个参数则存False。
    • action='store_false',存储False值,外部不传这个参数则存True。
    • action='append',存储为列表。用于可多次指定的选项。默认值若非空,也会存到列表且在第一位。
    • action='append_const',存储列表,并将由const指定的值加到列表中。
    • action='count',计算选项参数出现的次数;
    • action='help',打印当前解析器中的选项和参数的完整帮助信息,然后退出。
    • action='version',有一个version参数在add_argument中出现,打印该信息并退出。该选项存在时程序不会继续往后运行。
    • action='extend',存储一个列表,把每个参数值加到其中。
    parser = argparse.ArgumentParser()
    parser.add_argument('-z', action='store_const', const=3)
    parser.add_argument('-x', action='store_true')
    parser.add_argument('-y', action='store_false')
    parser.add_argument('-f','--foo', action='append')
    parser.add_argument('-c', action='count')
    parser.add_argument('-a','--all', action='extend', nargs="+")
    
    args = parser.parse_args('-c -f abc -a a1 a2 a3 -f xyz -c -ccc -z'.split())
    print(args)
    
    Namespace(c=5, x=False, y=True, z=3, foo=['abc', 'xyz'], all=['a1', 'a2', 'a3'])
    

    只有对命令行参数产生消耗的action才能对位置参数使用,如store、append、extend。

    可以通过传递Action子类或实现类似接口的其他对象来指定任意操作。

  • nargs
    将不同数量的命令行参数关联到同一个动作。可选的值有:

    • nargs=n:整数值,表示把命令行中的n个参数聚集到一个列表中。nargs=1时会产生单元素列表。
    • nargs='?':不在命令行指定该选项时,该选项值为default给定的默认值,在命令行指定了选项但是没有给值,选项就使用const给定的值。一般用于允许可选的输入或输出文件。
    • nargs='*',所有当前命令行参数聚集到一个列表中。
    • nargs='+',所有当前命令行参数聚集到一个列表中,没有命令行参数时会产生错误信息。

    nargs不填的时候,解析行为由action决定。
    不需要在命令行传值的action,nargs=0。

  • const
    不从命令行读取,但被一些action和nargs需要的常数。

  • default
    参数在命令行未出现时应当使用的值。

  • type
    命令行参数应当被转换成的类型。
    不要使用type=bool,非空字符串都会转为True。
    在引发AgrumentTypeError、TypeError、ValueError时,type能处理错误并显示信息。

  • choices
    由一组限定的值组成的序列,该命令行参数的值只能在这个范围内选择。不在范围内会显示错误。

  • required
    此命令行选项是否可省略。选项参数设置require=True时,会变为必选参数。

  • help
    一段此参数作用的简单描述。add_argument接收到的大部分关键字参数,都能在help文本以格式化的形式调用,%(default)s%(type)s等。

    设置help=argparse.SUPPRESS时,该选项不会在帮助信息中显示。

  • metavar
    帮助信息中代指参数的名称,默认会把dest参数的值作为这个名称。
    可以用metavar自定义这个代指使用的名称。

    >>> # 不使用metavar
    >>> parser.add_argument('bar')
    >>> parser.add_argument('--foo')
    usage: test.py [-h] [--foo FOO] bar
    
    >>> # 使用metavar
    >>> parser.add_argument('bar', metavar="XXX")
    >>> parser.add_argument('--foo', metavar="YYY")
    usage: test.py [-h] [--foo YYY] XXX
    

    metavar只影响在帮助信息中的显示,解析结果的属性名称还是由dest决定。

  • dest
    dest指命令行输入的值在parse_args解析后的属性名称,也是放到命名空间后的属性名称。
    默认情况下,位置参数的destadd_argument的第一个参数;选项参数的dest是第一个长选项字符串去掉前缀--后的部分,如果不指定长选项,就用第一个短选项去掉-做为dest。长选项字符串中带-的话,会在属性名称中被转换为_

    parser = argparse.ArgumentParser()
    # 位置参数使用第一个字符串做名称
    parser.add_argument('xx', 'yy')
    # 使用短选项做名称
    parser.add_argument('-a')
    # 使用长选项做名称
    parser.add_argument('-b', '--bar')
    # 使用长选项做名称,且横线转为下划线
    parser.add_argument('-c', '--count-num')
    # 指定dest则以指定的名称为属性名
    parser.add_argument('-d', '--decode', dest='code')
    
    args = parser.parse_args('a1 -a 3 -b 5 -c 6 -d 1'.split())
    print(args)
    
    Namespace(xx='a1', a='3', bar='5', count_num='6', code='1')
    
  • deprecated
    参数的使用是否已被弃用。用于一些在开发后期移除的命令。


4 parse_args()方法

ArgumentParser.parse_args(args=None, namespace=None)
将参数字符串转换为对象,并将其设为命名空间的属性值。
args是要解析的字符串列表,默认从sys.argv取。
namespace是用于获取属性的对象,默认是空的Namespace对象。

4.1 参数args

4.1.1 基本语法

parser.add_argument("-f", "--foo")
# 选项和值分为两个字符串传入
parser.parse_args("-f 5".split())
# 对于长选项可以和值在同一个字符串,用=分开
parser.parse_args("--foo=5".split())
# 短选项可以和值连在一起
parser.parse_args("-f5".split())

# 多个短选项如果只有最后一个需要输入值,就能并在一起
parser.add_argument("-x", action="store_true")
parser.add_argument("-y", action="store_true")
parser.add_argument("-z")
parser.parse_args("-xyzZ".split())

4.1.2 包含-的参数

# 参数值带有前缀-,可以单独插入--,表示后面的内容是一个位置参数
>>> parser.add_argument('bar')
>>> parser.parse_args("-- -1".split())
Namespace(bar='-1')

4.1.3 参数缩写

默认情况下允许将长选项缩写为前缀,只要缩写不会产生歧义。

>>> parser.add_argument('-ba135')
>>> parser.add_argument('-ba246')
>>> parser.parse_args("-ba1 xxx".split())
Namespace(ba135='xxx', ba246=None)
>>> parser.parse_args("-ba yyy".split())
usage: test.py [-h] [-ba135 BA135] [-ba246 BA246]
test.py: error: ambiguous option: -ba could match -ba135, -ba246

4.2 参数namespace

Namespace的对象。Namespace实例只是简单的可以存放属性的对象。
当需要为一个已存在的对象赋值时,可以指定参数namespace=对象名称


5 添加子命令

5.1 添加子命令的方法

添加子命令的格式如下:

ArgumentParser.add_subparsers(
    [title][, description][, prog][,parser_class][, action]
    [, option_strings][, dest][, required][, help][, metavar]
)

title:help信息中显示的子命令的名称。默认是“subcommands”。
description:帮助中对子命令的描述,默认None。
prog:在子命令的帮助信息的usage处展示的名称。
parser_class:创建子解析器的类。默认是当前解析器的类ArgumentParser。
action:当此参数在命令行中出现时要执行动作的基本类型。
dest:将被用于保存子命令名称的属性名;默认为None。
required:是否必选,默认为False。
help:在帮助中输出的子命令帮助信息,默认为 None。
metavar:帮助信息中子命令的替代名称。

5.2 使用示例

# 创建解析器并添加参数
parser = argparse.ArgumentParser()
parser.add_argument('--all', action="store_true", help='all help')

# 子解析器控制器
subparsers = parser.add_subparsers(title="子命令", help="子命令帮助", description="子命令简介")
# 子解析器a
parser_a = subparsers.add_parser("cmda", help="子命令a")
parser_a.add_argument('bar', type=int, help='bar help')
# 子解析器b
parser_b = subparsers.add_parser("cmdb", help="子命令b")
parser_b.add_argument('--baz', choices=('X', 'Y', 'Z'), help='baz help')

print("主解析器的帮助信息")
parser.print_help()
print("子解析器a的帮助信息")
parser_a.print_help()
print("子解析器b的帮助信息")
parser_b.print_help()

帮助信息打印结果

===主解析器的帮助信息===
usage: test.py [-h] [--all] {cmda,cmdb} ...
options:
  -h, --help   show this help message and exit
  --all        all help
子命令:
  子命令简介
  {cmda,cmdb}  子命令帮助
    cmda       子命令a
    cmdb       子命令b
    
===子解析器a的帮助信息===
usage: test.py cmda [-h] bar
positional arguments:
  bar         bar help
options:
  -h, --help  show this help message and exit
  
===子解析器b的帮助信息===
usage: test.py cmdb [-h] [--baz {X,Y,Z}]
options:
  -h, --help     show this help message and exit
  --baz {X,Y,Z}  baz help

子解析器的帮助信息只会包含自己的信息,没有其它子解析器和父解析器的信息。

5.3 子命令使用别名

创建子解析器时,可以用add_parser方法可以使用alias参数把多个字符串关联到同一个子解析器上。

subparsers.add_parser("cmda", alias=['CMDA'])

5.4 子命令关联函数

子解析器的方法set_defaults(**kwargs),可以接收一个函数作为绑定。

def foo_and_bar(args):
    return args.foo + args.bar

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()

parser_a = subparsers.add_parser("cmda")
parser_a.add_argument('bar', type=int)
parser_a.add_argument('foo', type=int)
parser_a.set_defaults(func=foo_and_bar)

args = parser.parse_args("cmda 1 2".split())
print(args)
print(args.func(args))
Namespace(bar=1, foo=2, func=<function foo_and_bar at 0x...>)
3

6 其它

6.1 参数分组显示

ArgumentParser.add_argument_group(title=None, description=None, *[, argument_default][, conflict_handler])
默认情况下,帮助消息会分为位置参数和选项参数两组,add_argument_group可以自定义更好的分组。

parser = argparse.ArgumentParser()
group = parser.add_argument_group('circle')
group.add_argument('--pi', help='指定圆周率的精度', type=float, default=3.14)
group.add_argument('r', help='半径')
parser.print_help()
usage: [-h] [--pi PI] r
options:
  -h, --help  show this help message and exit
circle:
  --pi PI     指定圆周率的精度
  r           半径

6.2 互斥参数

ArgumentParser.add_mutually_exclusive_group(required=False)
创建互斥组,确保其中的参数只有一个在命令行出现。require为True时,表示互斥组中必须至少有一个在命令行出现。

6.3 部分解析

ArgumentParser.parse_known_args(args=None, namespace=None)
作用和parse_args一样,但是存在额外参数的时候不会产生错误。

6.4 打印帮助

打印简短描述:ArgumentParser.print_usage(file=None)
打印帮助信息:ArgumentParser.print_help(file=None)

file表示输出的位置,默认时sys.stdout

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值