热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:Python3+getopt解析命令行参数

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Python3+getopt解析命令行参数相关的知识,希望对你有一定的参考价值。一、说明在学C

篇首语:本文由编程笔记#小编为大家整理,主要介绍了Python3+getopt解析命令行参数相关的知识,希望对你有一定的参考价值。



一、说明

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

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

 


二、getopt实现


2.1 程序代码

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

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



import getopt
import sys
def _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}")
except getopt.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 in opts:
# -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"] = arg
return options_dict, args
def _usage():
print("getopt_test version 1.0")
print("-h print this message")
print("-n equ --name")
print("-p equ --profession")
class TestGetopt:
"""
sys.argv[index]武断地以空格来划分参数,并不能区分选项和选项值
sys.argv[index]不能乱序,取第一个参数为用户名,就必须在第一个参数输入用户名,不能在第二或别的地方输
我们使用getopt模块来解决这两个问题
"""
def __init__(self):
self.options_dict, self.args
= _parse_option()
def test_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类似且会被取代就不介绍了。



import argparse
def _parse_option():
"""所有要解析参数的文件加上这个函数"""
parser
= argparse.ArgumentParser()
# 默认会自动添加-h参数,-h的作用是打印各参数说明并使用exit退出。不想要原始的-h可设置add_help=False指示不自动添加
# parser = argparse.ArgumentParser(add_help=False)
# parser.add_argument()支持参数及各参数说明如下
# 开头的非关键字参数--可以是-开头的短格式,也可以是--开头的长格式。
# --其中短格式也支持-ltnp等多个参数连写的形式,但这多个连写的参数必须都已注册,不然程序会直接报错退出
# 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,没有则赋给长格式,没有再赋给短格式
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"])
return options, args
class TestArgparse:
"""所有要解析参数的类调用该函数进行解析即可"""
def __init__(self):
# options是optparse.Values类型并不是字典类型。optparse.Values类型可通过optparse.dest实现访问
# args是列表类型
self.options, self.args = _parse_option()
def test_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 运行截图

 

参考:

http://www.runoob.com/python3/python3-command-line-arguments.html

https://docs.python.org/3/library/argparse.html

https://stackoverflow.com/a/12818237



推荐阅读
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
author-avatar
大爱走钢索的人_738
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有