输出结果:
$ 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', '')] []
可以看到,author
和country
两个参数我们都只输入了一部分,但是getopt
依然进行了正确的解析。
总结
本文讲解了使用Python解析命令行参数的两种方式,一种是略显笨重的手动解析,即自己编写程序自定义解析;另一种则是调用现成、且更加健壮的getopt
模块来完成解析。
从此以后,我们终于可以摆脱繁琐的配置文件,用一种优雅简洁的方式来修改程序的行为了。