如何优雅地解析命令行选项(下)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 随着我们编程经验的增长,对命令行的熟悉程度日渐加深,想来很多人会渐渐地体会到使用命令行带来的高效率。 自然而然地,我们自己写的很多程序(或者干脆就是脚本),也希望能够像原生命令和其他程序一样,通过运行时输入的参数就可以设定、改变程序的行为;而不必一层层找到相应的配置文件,然后还要定位到相应内容、修改、保存、退出……

输出结果:

$ python test_getopt.py -d  -t
[('-d', ''), ('-t', '')]
[]

当然,如果输入的参数少于预期,也不会导致解析失败:

$ python test_getopt.py  -t
[('-t', '')]
[]

但要是给出了预期之外的参数,就会导致模块抛错:

$ python test_getopt.py -d  -t -k
Traceback (most recent call last):
  File "test_getopt.py", line 11, in <module>
    opts, args = getopt.getopt(sys.argv[1:], 'dt')
    ...
    raise GetoptError(_('option -%s not recognized') % opt, opt)
getopt.GetoptError: option -k not recognized

这样的处理逻辑也符合我们使用命令的体验,可以简单地理解为“宁缺毋滥”。

如果短参数相应的字母后带了一个冒号:,则意味着这个参数需要指定一个参数值。getopt会将该参数对应的下一个命令行参数作为参数值(而不论下一个参数是什么形式):

import sys
import getopt
opts, args = getopt.getopt(sys.argv[1:], 'd:t')
print(opts)
print(args)
# $ python test_getopt.py -d  -t
# [('-d', '-t')]
# []

此外,一旦getopt在预期接收到长短选项的位置没有找到以“--”或“-”开头的字符串,就会终止解析过程,剩下的未解析字符串均放在返回元组的第二项中返回。

$ python test_getopt.py -d d_value o --pattern -t
[('-d', 'd_value')]
['o', '--pattern', '-t']

类似地,longopts参数表示需要解析的长参数。

列表中的每一个字符串代表一个长参数:

import sys
import getopt
opts, args = getopt.getopt(sys.argv[1:], '', ["author", "country"])
print(opts)
print(args)
# $ python test_getopt.py --author  --country
# [('--author', ''), ('--country', '')]
# []

要解析带有参数值的长参数,还应在每个长参数后附带一个等于号(=),以标识该参数需要带值:

import sys
import getopt
opts, args = getopt.getopt(sys.argv[1:], '', ["author=", "country"])
print(opts)
print(args)
# $ python test_getopt.py --author justdopython --country
# [('--author', 'justdopython'), ('--country', '')]
# []

所以最终就得到了我们一开始的解析结果:

import sys
import getopt
opts, args = getopt.getopt(sys.argv[1:], 'd:t:', ["author=", "country=", "auto"])
print(opts)
print(args)
# $ python test_getopt.py -d today -t now --author justdopython --country China --auto
# [('-d', 'today'), ('-t', 'now'), ('--author', 'justdopython'), ('--country', 'China'), ('--auto', '')]
# []

解析完成后,我们再从opts中提取相应的值即可。

懒人福音

getopt除了替我们节省了编写命令行参数解析代码的时间和精力,另一方面还可以让你在输入命令行参数时少打几个字母——当然,严谨来讲,我们并不建议此类行为。慎用,慎用!

getopt对长参数的解析支持前缀匹配,只要输入的参数能够与某个指定参数唯一匹配,同样能够完成预期解析。

$ python test_getopt.py -d today -t now --auth justdopython --coun China --auto
[('-d', 'today'), ('-t', 'now'), ('--author', 'justdopython'), ('--country', 'China'), ('--auto', '')]
[]

可以看到,authorcountry两个参数我们都只输入了一部分,但是getopt依然进行了正确的解析。

总结

本文讲解了使用Python解析命令行参数的两种方式,一种是略显笨重的手动解析,即自己编写程序自定义解析;另一种则是调用现成、且更加健壮的getopt模块来完成解析。

从此以后,我们终于可以摆脱繁琐的配置文件,用一种优雅简洁的方式来修改程序的行为了。

目录
相关文章
|
4月前
|
域名解析 网络协议 安全
在Linux中,想在命令行下访问某个网站,并且该网站域名还没有解析,如何做?
在Linux中,想在命令行下访问某个网站,并且该网站域名还没有解析,如何做?
|
3月前
|
Python
命令行解析工具 argparse
命令行解析工具 argparse
57 14
|
4月前
|
存储 Go UED
精通Go语言的命令行参数解析
【8月更文挑战第31天】
50 0
|
4月前
|
存储 Java 测试技术
解析 -XX:+UseCompressedOops JVM 选项
【8月更文挑战第21天】
63 0
|
4月前
|
SQL 分布式计算 算法
【python】python指南(二):命令行参数解析器ArgumentParser
【python】python指南(二):命令行参数解析器ArgumentParser
48 0
|
4月前
|
Go
【go笔记】使用标准库flag解析命令行参数
【go笔记】使用标准库flag解析命令行参数
|
4月前
|
Python
python命令行解析模块argparse
python命令行解析模块argparse
|
5月前
|
存储 Python 容器
`click`是一个用于构建命令行接口的Python包,它提供了简单、可组合的命令行解析器。
`click`是一个用于构建命令行接口的Python包,它提供了简单、可组合的命令行解析器。
|
7月前
|
存储 开发者 Python
Python中的argparse模块:命令行参数解析的利器
Python中的argparse模块:命令行参数解析的利器
71 2
|
7月前
|
存储 Linux Android开发
Rockchip u-boot阶段命令行和代码方式读取u盘内容并解析
Rockchip u-boot阶段命令行和代码方式读取u盘内容并解析
867 2

推荐镜像

更多
下一篇
DataWorks