前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python argparse标准库快速入门

Python argparse标准库快速入门

作者头像
乐百川
发布2020-02-18 16:02:33
8480
发布2020-02-18 16:02:33
举报

Python是一门非常好用的脚本语言,自然使用它来开发命令行程序也比较方便。而且Python的标准库中有一个名为argparse的库,可以非常方便的让我们把命令行参数转换成所需的数据格式。下面就让我们来看看如何使用argparse标准库吧。

如果想详细了解argparse的话,可以查看Python官方文档,目前已经出了中文版文档,极大的方便了我们中国开发者,虽然有些地方没有完整翻译,但是已经完全够用了。

初见argparse

首先来看看argparse的基本用法,下面是最简单的一个例子。可以看到argparse标准库其实用起来很简单,分成三个步骤:

  1. 创建ArgumentParser对象
  2. 使用add_argument方法添加参数
  3. 使用parse_args方法接受并解析对象

下面我们就依次来看看这些步骤吧。

代码语言:javascript
复制
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-from', type=str)
parser.add_argument('-to', type=str, default='everyone')

args = parser.parse_args('-from yitian'.split(' '))
print(args)

# 运行结果
# Namespace(from='yitian', to='everyone')

ArgumentParser

ArgumentParser是最重要的一个类,我们要使用argparse标准库就必然需要创建这个类的实例。如果有需要的话,可以通过在构造函数中设置各种参数的方式来修改ArgumentParser类的行为。由于参数项比较多,所以官方文档建议我们使用关键字参数的方式来添加参数。

  • prog - 程序的名称(默认:sys.argv[0]),默认是Python程序的文件名
  • usage - 描述程序用途的字符串(默认值:从添加到解析器的参数生成)
  • description - 在参数帮助文档之前显示的文本(默认值:无)
  • epilog - 在参数帮助文档之后显示的文本(默认值:无)
  • parents - 一个 ArgumentParser 对象的列表,它们的参数也应包含在内。假如多个parser有一些可以共享的参数,可以通过设置子parser的方式来共享
  • formatter_class - 用于自定义帮助文档输出格式的类
  • prefix_chars - 可选参数的前缀字符集合(默认值:’-’)
  • fromfile_prefix_chars - 当需要从文件中读取其他参数时,用于标识文件名的前缀字符集合(默认值:None
  • argument_default - 参数的全局默认值(默认值: None),假如需要给所有参数指定一个相通的默认值,可以修改这个,如果希望全局禁用默认值,可以使用argparse.SUPRESS
  • conflict_handler - 解决冲突选项的策略(通常是不必要的)
  • add_help - 为解析器添加一个 -h/--help 选项(默认值: True
  • allow_abbrev - 如果缩写是无歧义的,则允许缩写长选项 (默认值:True

add_argument方法

有了Parser实例,就可以调用它的add_argument方法来添加程序可以接受的参数了。这个参数比较复杂,功能也十分强大。

  • name or flags - 一个命名或者一个选项字符串的列表,例如 foo-f, --foo
  • action - 当参数在命令行中出现时使用的动作基本类型。
  • nargs - 命令行参数应当消耗的数目。
  • const - 被一些 actionnargs 选择所需求的常数。
  • default - 当参数未在命令行中出现时使用的值。
  • type - 命令行参数应当被转换成的类型。
  • choices - 可用的参数的容器。
  • required - 此命令行选项是否可省略 (仅选项可用)。
  • help - 一个此选项作用的简单描述。
  • metavar - 在使用方法消息中使用的参数值示例。
  • dest - 被添加到 parse_args() 所返回对象上的属性名。

参数名

方法的第一个参数是参数名称,可以是一个字符串(name)或者是-开头的一组字符串(flags),前者是位置参数,会按照添加的顺序被读取;后者是关键字参数,可以以任意顺序指定。如果指定的是关键字参数(flags),可以同时添加缩写和完整名,它们分别需要用---来做前缀。

代码语言:javascript
复制
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('foo')
parser.add_argument('bar')
parser.add_argument('-f', '--ff', action='store_true')

args = parser.parse_args('FOO BAR -f'.split(' '))
print(args)
args = parser.parse_args('--ff BAR FOO'.split(' '))
print(args)

'''运行结果,注意指定的参数和获取到的结果的不同
Namespace(bar='BAR', ff=True, foo='FOO')
Namespace(bar='FOO', ff=True, foo='BAR')
'''

action(行为)

接下来介绍的参数都是关键字参数,可以按需制定。这里比较重要的一个是action,它指定了读取参数接下来要做什么。这部分可以看官方文档,介绍的比较全面,而且有对应的例子。我这里只简单介绍一下。

  • store和store_const用来保存具体的值,他们之间有一些区别,一会再介绍。
  • store_true和store_false比较方便,可以用来设置一些开关参数。例如我想指定-f的时候开启某个功能,忽略这个参数的时候不执行,就可以把它的行为指定成store_true,然后在程序中就可以得到f名字的参数真值,然后简单的条件判断就可以了。
  • append和append_const会将参数存储成一个列表。
  • count会存储参数出现的次数。常见用法是指定日志输出级别,例如有的程序-v会显示简单输出,-vv会显示复杂输出。

甚至如果需求更复杂的话,还可以自己实现一个新的Action类,然后添加给add_argument方法。

nargs(参数数目)

这个参数指定你的程序可以接受的参数个数,可以使用以下几个值:

  • N(一个正整数),表示后面的N个值会被读取为参数,注意指定为1的话会变成一个单元素列表。
  • ?,和正则表达式里的概念差不多,后面的一个值会被读取,如果没有的话会从default读入。
  • +,后面的多个值会被读取,如果没有会抛出异常。
  • ?,后面的多个值会被读取,没有值的话也可以。
  • argparse.REMAINDER,它会将后面所有值读取为一个参数,通常用作向其他命令行传递参数用。

默认情况下nargs会按照action的类型来判断参数个数,store和store_const会读取后面的一个值作为参数。

const

这个参数需要和带有const的action来配合使用。

default

指定参数的默认值。这里有一个很有趣的点,如果你看官方文档比较仔细的话,可能会产生一个和我一样的疑问:store_const和const配合使用可以指定默认值,而store和default也可以指定默认值,那么它们之间有什么区别呢?其实区别还是蛮大的,看看下面这个例子就明白了。

代码语言:javascript
复制
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-foo', action='store', nargs='?', default=10, const=20)

print(parser.parse_args('-foo 0'.split(' ')))
print(parser.parse_args('-foo'.split(' ')))
print(parser.parse_args(''))

'''
Namespace(foo='0')
Namespace(foo=20)
Namespace(foo=10)
'''
  1. 当foo参数完全忽略的时候,会使用default的值。
  2. 当指定了foo参数,但没有指定后面的值时,会使用const的值。
  3. 当指定了foo参数和后面的值时,会使用我们指定的值。

type

这个是指定参数类型的,int、float、str那些。当然比较特殊的一个是open,它会将参数作为文件来打开。

如果默认的open还不能满足,还可以使用argparse.FileType,它提供了读写模式、文件编码、缓冲区大小等详细设置。

代码语言:javascript
复制
parser.add_argument('bar', type=argparse.FileType('w'))

甚至有需求的话,这里还可以使用我们自己的函数,只要它的参数是一个字符串,返回值是转换以后的值就可以。

choices

如果确认参数范围限定是几个定值,可以使用choices参数来指定,可接受的值包括字面值列表以及range函数。

required

指定参数是否是必须的。

metavar和dest

metavar参数用来指定参数的显示名称,而dest用来指定参数底层使用的属性名。

注意下面的程序输出,foo参数只修改了metavar,所以在帮助信息输出中发生了变化,但是在Namespace底层仍然使用foo保存值。而bar参数修改了dest,所以底层属性名发生了变化,但是在帮助信息中并没有什么改变。

代码语言:javascript
复制
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-foo', metavar='foooo')
parser.add_argument('-bar', dest='barrrr')

parser.print_help()
print(parser.parse_args(''))

'''
usage: argparse_sample.py [-h] [-foo foooo] [-bar bar]

optional arguments:
  -h, --help  show this help message and exit
  -foo foooo
  -bar bar
Namespace(barrrr=None, foo=None)
'''

help

有条件的话最好给每个参数添加帮助信息,这样使用者在用-h命令的时候就可以看到参数的帮助信息了。

parse_args方法

编辑好了参数,就可以调用parse_args方法来处理参数了,它会返回一个命名空间对象,包含了解析之后的参数。如果要测试方法的话,可以手动给它传递一组参数,否则的话,它会自动从命令行参数读取。另外它还支持几个比较有用的特性:

  • 如果参数比较长,可以使用等号来连接参数与值,例如-foo=bar
  • 如果参数是单字母长度的,可以将参数和值直接写在一起。
代码语言:javascript
复制
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-foo')
parser.add_argument('-b')

print(parser.parse_args('-foo=bar'.split()))
print(parser.parse_args('-bX'.split()))

'''
Namespace(b=None, foo='bar')
Namespace(b='X', foo=None)
'''

另外还支持默认无歧义的参数缩写。

代码语言:javascript
复制
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-f1aaaaaaaaaa')
parser.add_argument('-f2aaaaaaaaaa')

print(parser.parse_args('-f1 a -f2 b'.split(' ')))

命名空间对象

前面也看到了,解析完参数返回的值是命名空间对象,它用起来非常简单,直接访问属性值就可以了。

代码语言:javascript
复制
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-a')
parser.add_argument('-b')

args = parser.parse_args('-a a -b b'.split(' '))
print(args.a)

# a

其他特性

argparse还支持一些其他特性,这里就不多做介绍了,详情请直接参考官方文档。

  • 子parser。有些程序支持子命令,这时候可以使用子parser创建更复杂的parser。
  • FileType。更详细的设置文件参数的方法。
  • 参数组。如果参数比较多,可以使用参数组的方式将功能相近的参数进行分组,这样不管是开发人员还是使用人员都能更清晰的使用参数。
  • 互斥参数组。如果某些参数不能同时使用,可以将它们加到互斥参数组中。
  • 部分解析。默认情况下parse_argument在遇到未知参数的时候会报错,如果需要保存这些参数传递给其他命令行的时候,可以使用parse_known_args方法。它不会因为未知参数报错, 而且会将所有不认识的参数存储成一个列表作为第二个返回值。

简单实例

扯了大半天,大家可能还是有点不会用argparse,不过其实只要看一个简单的例子就可以了。保存下面的文件,然后用命令行调用,看看不同的参数会有什么输出。

代码语言:javascript
复制
import argparse

parser = argparse.ArgumentParser(prog='ParserSample',
                                 description='简单实例程序,学习如何解析命令行参数',
                                 epilog='很简单就可以学会')

parser.add_argument('greeting', type=str, help='问候信息,必需')
parser.add_argument('-fromm', default='yitian', type=str, help='发送人,默认是易天')
parser.add_argument('-to', default='everyone', type=str, nargs='*', help='接收人,默认是所有人')
parser.add_argument('-p', action='store_true', help='是否添加感叹号')

args = parser.parse_args()

output = f'{args.fromm} say {args.greeting} to {args.to}'
if args.p:
    output = output + '!'

print(output)

'''
usage: ParserSample [-h] [-fromm FROMM] [-to [TO [TO ...]]] [-p] greeting

简单实例程序,学习如何解析命令行参数

positional arguments:
  greeting           问候信息,必需

optional arguments:
  -h, --help         show this help message and exit
  -fromm FROMM       发送人,默认是易天
  -to [TO [TO ...]]  接收人,默认是所有人
  -p                 是否添加感叹号

很简单就可以学会
'''
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 初见argparse
  • ArgumentParser
  • add_argument方法
    • 参数名
      • action(行为)
        • nargs(参数数目)
          • const
            • default
              • type
                • choices
                  • required
                    • metavar和dest
                      • help
                      • parse_args方法
                        • 命名空间对象
                        • 其他特性
                        • 简单实例
                        相关产品与服务
                        容器服务
                        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档