Python-argprase命令行选项、参数和子命令解析

写在前面,欢迎大家访问我的博客:Scout He

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

1、创建一个解析器

使用argparse的第一步就是创建一个解析器对象,即ArgumentParser对象,这个对象有多个参数,我们一个一个来讲。

parser = argparse.ArgumentParser(
    prog='',        # 程序名称
    description='', # 在帮助文档前显示的文本
    epilog='',      # 在帮助文档后显示的文本
    add_help=True,  # 是否添加帮助选项,即-h,默认True
    usage=''        # 设定usage中显示的文本,默认为:程序名称+-h
    )

# 首先创建一个对象
parser = argparse.ArgumentParser(usage="how to use",prog='Name',description='Front description',epilog='Back description')

其中各个参数的对应位置如下图:
Python-argprase命令行选项、参数和子命令解析_第1张图片

在设置了usage之后,图中对应的就会变为:
usage: how to use
这些就是基本的常用参数。其他用法请参考官方文档。


2、为解析器添加参数

添加参数使用add_argument()方法,我们将逐个讲解,因为这些都比较重要:

ArgumentParser.add_argument(
    name or flags...    # 一个位置参数,或者指定名字的参数
                        # 即添加的此参数的名字
    [, action]          # 
    [, nargs]
    [, const]
    [, default]
    [, type]
    [, choices]
    [, required]
    [, help]
    [, metavar]
    [, dest])

2.1、Name or flags

首先我们要搞清楚,这个add_argument() 函数到底添加的是什么。为什么第一个参数不带括号,后面的却带。

2.1.1、类比函数传参

就像函数传参一样,一个程序不可能只传入一个数据,在函数参数里有两种常用的传参方式:关键字参数,默认参数

def printinfo( name, age = 35 )
# 这里 name 就是关键字参数
# age 自带默认值,就是默认参数
def printinfo( name, gander, age = 35 ):
    print ("名字: ", name)
    print ("性别: ", gander)
    print ("年龄: ", age)
printinfo( "何小岳" ,"男")
# 名字:  何小岳
# 性别:  男
# 年龄:  35

但是如果将传入的参数改变位置,那么结果就也会变,这就是位置传参,函数根据输入的数据的位置传入参数
名字: 男 性别: 何小岳 年龄: 35
而带有默认值的名字就只能通过指定参数的方法传入

printinfo( age=50, name="何小岳" )
# 名字:  何小岳
# 年龄:  50

2.1.2、add_argument()传参

因此,与函数传参相同,这里传入的参数也是分为位置传参,和指定参数传入。
而与之不同的是:
1、函数传参不能限制传入的类型,也就是唯一的限制条件就是默认值
2、argparse 传参则可以通过后续的选项来设置限制

name

即我们每用 add 一次,就会设置一个参数,例如:

# 针对 add_argument() 的第一个参数 name or flags 
# 其也是分为两种传参方式,位置,和指定名称
parser.add_argument('first')
parser.add_argument('second')
args = parser.parse_args()

print(args.first+args.second)

python .\argparse_learn.py 1 2
12

这里就将输入的连个字符串连接了起来,是通过位置传参的方式
如果输入 -h 就会发现在 usage 中,两个参数的顺序是按添加的顺序显示的
usage: My argparse [-h] first second

flags

这个就是指定名字传参了

parser.add_argument('--first')
parser.add_argument('--second')

如果将上面的两个参数改为这样,再次以同样的方式输入的话就会报错:

python .\argparse_learn.py 1 2
usage: My argparse [-h] [–first FIRST] [–second SECOND]
My argparse: error: unrecognized arguments: 1 2

所以指定传参只能通过命令行来指定参数传递,比如这样:

python .\argparse_learn.py --first 1 --second 2
12

但是这样还有个问题,即每次都要输入完整的单词,太长了怎么办

parser.add_argument('-f','--first')
parser.add_argument('-s','--second')

args = parser.parse_args()
print(args.first+args.second)

python .\argparse_learn.py -s 2 -f 3
32

这样再加一个 -f 一位的缩写即可通过短的名字来添加函数,需要特别注意的是:
print 的时候,需要写全称,因为其中默认的变量名是全称。
-f FIRST, --first FIRST
-s SECOND, --second SECOND


2.2 Action

这个指的是将命令好参数与动作相关联,默认的是
1.store --存储参数的值,上文中可以打印出参数就是因为这个参数
2.sotre_const 这个通常和const结合使用,用来存储const命名参数指定的值
即在命令行中通过const指定参数的值

parser.add_argument('-f','--first',action='store_const',const="10")
parser.add_argument('-s','--second')
args = parser.parse_args()

print(args.first+args.second)
> python .\argparse_learn.py  -s 2 -f
102
# 这时如果在指定参数的值就会报错
> python .\argparse_learn.py  -s 2 -f 10
usage: My argparse [-h] [-f] [-s SECOND]
My argparse: error: unrecognized arguments: 10

3.store_true
store_false
这两个分别指定参数值为true和false

parser.add_argument('-f','--first',action='store_true')
print(args.first)
------
> python .\argparse_learn.py  -s 2
False

4.append,储存列表

parser.add_argument('-f','--first',action='append')
print(args)
------
> python .\argparse_learn.py  -f 1 -f 2 -f 3
Namespace(first=['1', '2', '3'], second=None)

5.append_const,储存const中的值,一般在多个参数需要在同一列表中存储常数时会有用。
6.count,计算一个关键字参数出现的次数

parser.add_argument('-f','--first',action='count')

python .\argparse_learn.py -fff
3

2.3、Nargs

这个参数可以使一个参数,一次添加多个值,变成可迭代对象

N----   #(一个整数),命令中N个参数,聚集形成一个列表
例:>>> parser.add_argument('-f', nargs=2)
Namespace(first=['a', 'b'])
----------  #这个等于是函数传参中的 *args ,可选传参,另外使用这个即可解决上文中,使用 const 无法在传参的问题
parser.add_argument('-f','--first',nargs="?",const= 10)

> python .\argparse_learn.py  -f 1
Namespace(first='1')
> python .\argparse_learn.py  -f
Namespace(first=10)
------
* and +----  # 所有参数都聚集到一个列表中,* 和 + 是一个作用,结果也相同
parser.add_argument('-f','--first',nargs="*"/"+")
> python .\argparse_learn.py  -f 1  2  3
Namespace(first=['1', '2', '3'])
不同的是,当输入为空时,+ 会报错,* 不会


2.4、const

通常在store_const, append_const中必须给出参数,其余默认为None
是常数值。


2.5 defult

指定在命令行参数未给出的默认值。
提供 default=argparse.SUPPRESS 导致命令行参数未出现时没有属性被添加。


2.6、type

指定输入类型,通常解析器默认读入的是字符串类型的,如果需要整数等其余类型需要指定type。
例如:int,float,ascii,ord等。

2.7、chorice

指定参数只能从一个容器中选择,例如:

parser.add_argument('-f','--first',choices=[110,120,119])

> python .\argparse_learn.py  -f 100
usage: My argparse [-h] [-f {110,120,119}] [-s SECOND]
My argparse: error: argument -f/--first: invalid choice: '100' (choose from 110, 120, 119)

2.8、required

指定参数为必要参数:required=True


2.9、help

这是当在命令行加入 -h 参数时,出现在参数后面的解释。

parser.add_argument('-f','--first',choices=[110,120,119],help="learning")

> python .\argparse_learn.py  -h
usage: My argparse [-h] [-f {110,120,119}]

Front description

optional arguments:
  -h, --help            show this help message and exit
  -f {110,120,119}, --first {110,120,119}
                        learning #就是这里

Back description

2.10、metavar

这个参数的意思是,改变的参数显示名字。
我们先看默认情况下:

parser.add_argument('-f','--first',help="learning")
args = parser.parse_args()
print(args.first)

> python .\argparse_learn.py  -h
usage: My argparse [-h] [-f FIRST]

Front description

optional arguments:
  -h, --help            show this help message and exit
  -f FIRST, --first FIRST
                        learning
# 这里两个参数的别名都是默认的FIRST,所以我们可以通过:
# args.first 来访问参数的值
> python .\argparse_learn.py  -f 2
2

如果设定metavar值:

parser.add_argument('-f','--first',help="learning",,metavar="fff")

# 这样其访问的名字就会变为fff
optional arguments:
  -h, --help           show this help message and exit
  -f fff, --first fff  learning

但是他只能改变显示名字,无法通过这个来访问元素,还是需要通过原来的值来访问。

> python .\argparse_learn.py  -f 2
2

> python .\argparse_learn.py  -f 2
Traceback (most recent call last):
  File ".\argparse_learn.py", line 15, in <module>
    print(args.fff)
AttributeError: 'Namespace' object has no attribute 'fff'

2.11、dest

这个dest就是metavar的默认值,所以修改dest即可改变属性的名称。

parser.add_argument('-f','--first',help="learning",metavar="fff",dest="new_name")
print(args.first)

> python .\argparse_learn.py  -f 2
AttributeError: 'Namespace' object has no attribute 'first'

# 可以看到在我们更改dest后,已经无法通过first来访问属性
print(args.new_name)
> python .\argparse_learn.py  -f 2
2
# 通过new_name即可访问属性

3、parse_args

这是最后一步,这个函数用来解析命令行中的字符串,并将其传入命名空间。

# 总结一下
# 第一步,创建解析器
parser = argparse.ArgumentParser(prog='My argparse',description='Front description',epilog='Back description')

# 第二步,添加参数
parser.add_argument('-f','--first',help="learning",metavar="fff",dest="new_name")

# 第三步,解读命令行
args = parser.parse_args()

# 最后通过args即可操作输入的参数了
# 就像个我上面打印的用法一样,通过属性名,访问属性值

这既是大部分的内容,其余少量的内容,请翻阅官方文档。

参考文章:
参考链接

你可能感兴趣的:(python)