python 参数解析器_Python中最好用的命令行参数解析工具

接下来只剩下 argparse 这一神器,它几乎能满足我对命令解析器的所有需求。它支持解析一参数多值,可以自动生成help命令和帮助文档,支持子解析器,支持限制参数取值范围等等功能。

身为老司机,还是得分享些干货精品学习资料的,推荐下小编创建的Python学习交流群556370268,这里都是一群爱好Python的小伙伴,每天还会直播和大家交流分享经验哦。

1、HelloWorld

不管学习什么东西,首先第一步都应该是掌握它的大体框架。

而 使用 argparse 前,框架很简单,你只需要记住这三行。

# mytest.py

import argparse

parser = argparse.ArgumentParser(deion="used for test")

args = parser.parse_args()

现在可以尝试一下

[root@localhost ~]# python mytest.py -h

usage: mytest.py [-h]

used for test

optional arguments:

-h, --help show this help message and exit

[root@localhost ~]#

[root@localhost ~]#

[root@localhost ~]# python mytest.py

[root@localhost ~]#

已经可以使用了。

1. 入门配置

这里先讲一下,比较常用的参数配置。

调试:debug

版本号:version

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--version', '-v', action='version',

version='%(prog)s version : v 0.01', help='show the version')

parser.add_argument('--debug', '-d', action='store_true',

help='show the version',

default=False)

args = parser.parse_args()

print("=== end ===")

上面debug处的配置,需要讲一下的是 action='store_true' 和 default = False 的作用和区别

store_true

default=False当我们执行 python mytest.py -v ,就会打印 version 里的内容。

当我们执行 python mytest.py -v ,就会打印 version 里的内容。

[root@localhost ~]# python mytest.py -v

mytest.py version : v 0.01

[root@localhost ~]#

一旦执行时,指定了参数 -v ,执行到 parser.parse_args() 就会退出程序,不会打印最后的 === end ===

2. 参数种类

参数可分为 必选参数(positional arguments) 和 可选参数(optional arguments)。

在argsparse 里如何实现呢?

必选参数

用单词做参数,默认就为必选参数

# mytest.py

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("name")

args = parser.parse_args()

print(args.name)

不指定name参数运行一下: python mytest.py

[root@localhost ~]# python mytest.py

usage: mytest.py [-h] name

mytest.py: error: too few arguments

[root@localhost ~]#

如预期一样,报错了,说缺少参数。那我们指定一下: python mytest.py name wangbm

[root@localhost ~]# python mytest.py wangbm

wangbm

[root@localhost ~]#

可选参数

有两种方式:

单下划线 - 来指定的短参数,如 -h ;

双下划线 -- 来指定的长参数,如 --help

# mytest.py

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("-v", "--verbosity", help="increase output verbosity")

args = parser.parse_args()

if args.verbosity:

print("verbosity turned on")

else:

print("verbosity turned off")

试着运行一下 python mytest.py ,不会报错。

[root@localhost ~]# python mytest.py

verbosity turned off

[root@localhost ~]#

3. 参数类型

有的参数,是字符串,有的参数,是数值。

为了对命令行中的参数进行有效的约束,我们可以事先对参数的类型进行声明。argparse 会对参数进行校验,不通过时,会直接抛出错误。

# mytest.py

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("name")

parser.add_argument("age", type=int)

args = parser.parse_args()

print(args.name)

print(args.age)

测试一下唄。

[root@localhost ~]# python mytest.py wangbm eighteen

usage: mytest.py [-h] name age

mytest.py: error: argument age: invalid int value: 'eighteen'

[root@localhost ~]#

[root@localhost ~]# python mytest.py wangbm 18

wangbm

18

[root@localhost ~]#

你看,写 eighteen 就不行,提示类型不合法,只有写 18 才行。

4. 互斥参数

有些参数,是互斥的,有你无我。比如,性别。

在 argparse 中如何实现?

import argparse

parser = argparse.ArgumentParser()

group = parser.add_mutually_exclusive_group()

group.add_argument("-m", "--male", action="store_true")

group.add_argument("-f", "--female", action="store_true")

args = parser.parse_args()

如果同时指定了这两个参数,就会报错。

[root@localhost ~]# python mytest.py -f

[root@localhost ~]# python mytest.py -m

[root@localhost ~]# python mytest.py -m -f

usage: mytest.py [-h] [-m | -f]

mytest.py: error: argument -f/--female: not allowed with argument -m/--male

[root@localhost ~]#

5. 可选值

如果是性别,可以像上面那样放在两个参数里然后用互斥组来约束,也可以放在一个参数里,在argparse里限制再在外层做判断。

# mytest.py

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("-g", "--gender", default='male',

choices=['male', 'female'])

args = parser.parse_args()

print(args.gender)

试着执行一下,发现性别只能是男或女,不能为人妖。

[root@localhost ~]# python mytest.py --gender male

male

[root@localhost ~]# python mytest.py --gender female

female

[root@localhost ~]#

[root@localhost ~]#

[root@localhost ~]# python mytest.py --gender other

usage: mytest.py [-h] [-g {male,female}]

mytest.py: error: argument -g/--gender: invalid choice: 'other' (choose from 'male', 'female')

[root@localhost ~]#

6. 指定文件

经常会有那种要在脚本中指定配置文件或者其他文件的需求。可以使用下面的配置

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--file', '-f', action='append',

dest='files',

help=('additional yaml configuration files to use'),

type=argparse.FileType('rb'))

args = parser.parse_args()

dest=files ,是说将命令行中, --file 的参数值赋值给变量files,你可以用args.files访问。

action=append ,由于我们会有指定多个文件的需求,那就指定多次 --file ,argparse会将其放在一个list里。

type=argparse.FileType('rb') ,既然是指定文件,那么参数应该为路径,并指定打开模式为rb,如果如果要取得文件内容,可以用 args.files[0].read()

身为老司机,还是得分享些干货精品学习资料的,推荐下小编创建的Python学习交流群556370268,这里都是一群爱好Python的小伙伴,每天还会直播和大家交流分享经验哦。

7. 子解析器

如果你对命令行,有过足够多的接触,就会知道有些情况下会有子解析器。

这里我以自己工作中,碰到的例子来举个例子。

cloud-init --debug single -name mymodule

其中 single 后面是一个子解析器。

# cloud-init.py

def main_single(name, args):

print("name: ", name)

print("args: ", args)

print("I am main_single")

# 添加一个子解析器

subparsers = parser.add_subparsers()

parser_single = subparsers.add_parser('single',help='run a single module')

# 对single 子解析器添加 action 函数。

parser_single.set_defaults(action=('single', main_single))

# require=True,是说如果命令行指定了single解析器,就必须带上 --name 的参数。

parser_single.add_argument("--name", '-n', action="store",

help="module name to run",

required=True)

args = parser.parse_args()

(name, functor) = args.action

if name in ["single"]:

functor(name, args)

执行命令 cloud-init single -name mymodule ,输出如下

name: single

args: Namespace(action=('single', ), debug=False, file=None, name='mymodule')

I am main_single

以上就是关于 argparse 工具的使用方法,你学会了吗?

python根据需求完成一个TXT解析器的简单开发 一 修改说明: 需求一: 一开始说要解析UECapabilityInfo 消息里的supportedBandCombination-r10 这个IE里的CA组合转化成易阅读的表现形式. 我以为一组CA组合就是一组: bandEUTRA-r10 ca-BandwidthClassUL-r10 ca-BandwidthClassDL-r10 supportedMIMO-CapabilityDL-r10 功能实现: 有效信息筛选:于是就用循环把UECapabilityInformation的数据里每一行作为一个元素放到list里面 然后用bandEUTRA-r10作为一组CA的识别信息、在筛选出同组ca-BandwidthClassUL-r10、ca-BandwidthClassDL-r10、supportedMIMO-CapabilityDL-r10的信息,添加保存到字符串,然后再把字符串作为元素添加到list去。最后遍历list的元素写入目标文件 需求二: 然后收到反馈CA组合的理解是错误的。一组CA组合应该是以大括号作为识别的,里面可能包含多组: bandEUTRA-r10: ca-BandwidthClassUL-r10 ca-BandwidthClassDL-r10 supportedMIMO-CapabilityDL-r10 CA组合识别原理:在查看UECapabilityInformation内的CA组合后 发现CA组合内第一个 bandEUTRA-r10因为比其他bandEUTRA-r10多了一层的CA组合的大括号,所以如果给每一行增加索引的话就会发现除了第一个bandEUTRA-r10,其他bandEUTRA-r10到上一个supportedMIMO-CapabilityDL-r10的距离都是一样的,为了减少复杂度,我删除了所有’{’,这样所有除了所有CA组合第一个bandEUTRA-r10往上第四行是’}’其他bandEUTRA-r10的往上第四行都是supportedMIMO-CapabilityDL-r10 功能实现: 添加索引:便利时用了for enumerate()循环,这样便利时可以在循环时,自动为每个元素生成索引 CA组合识别:在识别到bandEUTRA-r10时,增加一个判断if datalist1[index-4].startswith(),如果bandEUTRA-r10的往上第四行是supportedMIMO-CapabilityDL-r10说明同组CA未结束,把筛选的有效信息强制类型转换后添加在上个元素末尾,反之则说明是个新的CA组合,往列表里添加一个新的元素。 需求三: 之后收到反馈CA组合虽然识别了,但是排序不行,需要按照CA组合支持的band进行排序 功能实现: 排序:于是我在识别完CA组合后,增加了一个循环和count(),用CA组合里的’-’给它们归类 比如1AA,11A,21AA是一类;1A-1A,2A-1AA,3A-1A是一类 在用一个间变量保存开头的band的数字,一个类把开头支持band的数字字母相同的CA组合归为一行 比如1A-21A,1A-22A一类1AA-2AA 1AA-3AA为一类 需求四: 之后收到反馈,CA组合分类不能只按照开头比较分类,不然一但数据多了会对查阅带来极大不便,应该按照每组CA组合bandEUTRA-r10的值进行判断,比如1AA-2AA,1A-2AA和1AA-2A应该归在同一行 实现原理:首先我想的是按位比较数字,但是因为字母的数量不稳定,数字的位置不一定对应,然后我就想把数字全部提取出来作为索引,在相应的索引后面添加同组元素,用dict来实现排序。难点就在于从字符串提取数字。后来在python的正则表达式找到相关的处理函数compile()(设置匹配对象类型)和findall()(找到所有匹配对象并以list返回)。 功能实现: 第二次排序:在上次的排序我保留了分类和从小到大的排序。方便提取索引时,索引也是从小到大。每遍历一个元素(CA组合有效信息),就compile()和findall(),从该元素提取数字组合(在compile()的参数添加()就能够使提取的内容成为一组数据),然后通过dict自带函数setdefault()添加索引,并可以设置索引值为list类型(dict类型的索引的值不可变,但如果类型为list,list的内容可以进行改动),避免重复索引,在本次遍历完成将元素添加到索引值对应的list去 需求五: 之后对程序进行测试,在测试test2时发现layers增加了fourlayers类型后,用来代表layers的数字2和4会影响分类结果。比如1AA(2)-1AA(2)和1A(4)-1A(2)会被归为两类。 test1:当CA组合的格式为xx-xx-xx-xx-xx(最长可识别为五位元素的组合,再长就需要修改代码) test2:当CA组合包含fourLayers test3:当CA组合缺失某种格式比如xx-xx时发现layers增加了fourlayers 功能实现: : 解除layers对排序的影响:用II 和 IV替代2,4来表示layers,测试后不影响阅读与分类 二、整体程序架构: 1.通过循环和自带的startswith()先将每组CA组合的有效信息识别 2.通过sorted()函数将所有CA组合从小到大排列 3.通过count()函数将所有CA组合根据格式不同分类 4.通过循环和正则表达式的split()对所有CAlist数据进行处理(用split处理只是防止出现不必要的错误) 5.通过循环和正则表达式compile()和findall()识别所有CA组合数字,并将同一组合的数字合为一个元素(在同一循环,用这个数字的元素作为一个dict的索引),用dict自带的setdefault()进行Key的添加顺便设置Key的值为list,避免Key重复,在用append把当前Key的字符串,添加到Key对应值的list去 6.最后对dict整体遍历,将每一个Key的值输出到文本去。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值