python getopt参数参数自动补全_Python3+getopt/argparse解析命令行参数

一、说明

在学C语言的时候就知道可以通过argc获取命令行参数个数,可以通过argv获取具体参数。但自己写的程序获取到的参数一是没有键值形式二是写的参数不能乱序,和系统命令不太一样。

但这种位置参数用起来还是很不方便的,还是很有必要弄清系统命令的那种参数该如何实现。这里我们介绍经典的getopt和pythonic的argparse。

二、getopt实现

2.1 程序代码

此程序中设置-h/-n/-p三个选项,-h不带值-n和-p带值;三个参数设置等价长格式--help/--name/--profession。

程序通过sys.argv[1:]来获取所有待解析参数,然后传到getopt进行解析,更多说明见代码注释。

importgetoptimportsysdef_parse_option():try:#第一个参数argv----传过来的要解析的参数数组。形如['-n', 'ls', '-p', 'programmer']

#第二个参数"hn:p:"----用于向getopt注册短格式。没有:表示该参数不带值,有:表示下一参数为该参数的值

#第三个参数[]----用于向getopt注册长格式。没有=表示该参数不带值,有=表示=号后边为其值(如果没有=号就以下一个参数为其值)

#第三个参数[]----[]不是可选的意思,这里是代码,[]表示该参数是个数组

#opts----以元组形式存放解析出的参数。形如[('-n', 'ls'), ('-p', 'programmer'), ('-h', '')]

#args----以数组形式存放按所有注册的格式未能解析参数

#系统参数可通过sys.argv[index]来获取,sys.argv[0]是本身文件名

print(f"will parse argv: {sys.argv[1:]}")

opts, args= getopt.getopt(sys.argv[1:], "hn:p:", ["help", "name=", "profession="])print(f"parsed argv: opts----{opts} args----{args}")exceptgetopt.GetoptError:#参数不符合注册格式要求报错

print("parameter format error")

_usage()

sys.exit(2)

options_dict={}#遍历所有元组

#getopt只会严格按照注册的格式解析参数,而不理解哪个短格式与哪个长格式等价,等价是我们这里设定短格式和长格式用同一响应造成的

#也就是说getopt并不理解-n和--name等价,他有-n就解析-n有--name就解析--name,两个都有就两个都解析。-n和--name等价是因为我们对这两个参数用同样的代码进行处理。

#比如执行python getopt_test.py -n ls --name=root,解析出的就是[('-n', 'ls'), ('--name', 'root')]

for opt, arg inopts:#-h与--help等价

if opt in ("-h", "--help"):

_usage()

sys.exit()#-n与--name等价

elif opt in ("-n", "--name"):

options_dict["user_name"] =arg#-p与--profession等价

elif opt in ("-p", "--profession"):

options_dict["user_profession"] =argreturnoptions_dict, argsdef_usage():print("getopt_test version 1.0")print("-h print this message")print("-n equ --name")print("-p equ --profession")classTestGetopt:"""sys.argv[index]武断地以空格来划分参数,并不能区分选项和选项值

sys.argv[index]不能乱序,取第一个参数为用户名,就必须在第一个参数输入用户名,不能在第二或别的地方输

我们使用getopt模块来解决这两个问题"""

def __init__(self):

self.options_dict, self.args=_parse_option()deftest_use_arg(self):print(f"options: {self.options_dict}")print(f"args: {self.args}")print(f"you are {self.options_dict['user_profession']} {self.options_dict['user_name']}!")if __name__ == "__main__":

obj=TestGetopt()

obj.test_use_arg()

View Code

2.2 运行截图

下图中依次以以下四种形式运行程序,观察getopt解析前后参数可对getopt有更直观理解

python getopt_test.py -h

python getopt_test.py-n ls -p programmer

python getopt_test.py-n ls -p programmer --name=lsx

python getopt_test.py-n ls -p programmer --name=lsx other1 other2

三、argparse实现

3.1 程序代码

python的getopt感觉就是C的封装,在使用上C的getopt类似,或者换言之还是比较麻烦的。我们下边使用argparse实现类似的功能。

直观感受上我们可以看到同样的功能代码量的减少,但其实更重要的是argparse多处理了很多我们没注意的细节,实际代码中也更推荐使用argparse。

另外python 3.2之前的版本参数解析库是optparse,用法和argparse类似且会被取代就不介绍了。

importargparsedef_parse_option():"""所有要解析参数的文件加上这个函数"""parser=argparse.ArgumentParser()#默认会自动添加-h参数,-h的作用是打印各参数说明并使用exit退出。不想要原始的-h可设置add_help=False指示不自动添加

#parser = argparse.ArgumentParser(add_help=False)

#开头的非关键字参数--可以是-开头的短格式,也可以是--开头的长格式

#action--参数操作动作

#store(赋值)/store_const(赋给定的常量值)/store_true(赋true)/store_false(赋false)/append(多次出现时拼成列表)

#count(赋出现的次数)/help(打印帮助)/version(打印--version参数)/extend(存成列表)。默认为store

#nargs--消费其后多少个参数作为其值

#const--当action为store_const时,要赋值变量的常量值

#default--当命令行没有该参数时,该参数的默认值。默认为None

#type--变量类型。可以是所有python的变量类型,默认是str

#choices--可给该参数传的值的可选列表

#required--参数是否必须。默认为false

#help--参数描述信息

#metavar--参数赋值形式示例

#dest--参数解析后赋值到的变量。默认先赋给dest,没有则赋给长格式,没有再赋给短格式

#default--参数的默认值。默认为None

parser.add_argument("-n", "--name",

metavar="NAME", dest="user_name", default="ls", type=str, help="get user name")

parser.add_argument("-p", "--profession",

metavar="PROFESSION", dest="user_profession", help="get user profession")#options--argparse.Namespace类型,存储解析到的参数

#args--list类型,存储其他无法解析的参数

#parse_args()方法在遇到没有承接方的参数时会报错error: unrecognized arguments:并直接exit退出

#options = parser.parse_args()

#args = None

#parse_known_args()方法在遇到未注测的参数时会把它放入args而不是报错退出

(options, args) =parser.parse_known_args()#默认解析sys.argv[1:],所以并不需要自己把sys.argv[1:]传过去。当然你也可以传入自己想解析的参数列表

#(options, args) = parser.parse_known_args(["need", "too", "parse", "param", "list"])

returnoptions, argsclassTestArgparse:"""所有要解析参数的类调用该函数进行解析即可"""

def __init__(self):#options是optparse.Values类型并不是字典类型。optparse.Values类型可通过optparse.dest实现访问

#args是列表类型

self.options, self.args =_parse_option()deftest_use_arg(self):print(f"options: {self.options}")print(f"args: {self.args}")print(f"you are {self.options.user_profession} {self.options.user_name}!")if __name__ == "__main__":

obj=TestArgparse()

obj.test_use_arg()

View Code

3.2 运行截图

参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值