在unix系统中,程序的执行常伴有一些配置选项,如
df -h
或
df --help
其中,-h和--help就代表把分区的大小以KB或MB等单位显示,以方便用户阅读
更复杂一些的,
./run.py -c configfile
或
./run.py --config=configfile
-c或--config为程序指定了一个配置文件,为程序提供一些必要的变量信息。
那么,像-h, --help, -c, --config这些配置选项,Python是怎么获取的呢?答案就是getopt模块。
getopt模块提示了两个函数来满足这个需求:getopt.getopt和getopt.gnu_getopt,好么两个方法有什么不同呢?请看下面的代码例子:
import sys
import getopt
cmd_params = sys.argv[1:]
print(cmd_params)
opts, args = getopt.getopt(cmd_params, "c:h", ['help', 'config='])
print(opts)
for option, parameter in opts:
if option == '-h' or option == '--help':
print("help information")
if option in ('-c', '--config'):
print("Using configeration file %s" % parameter)
print(args)
其中的sys.argv保存了程序执行时从命令行中获取中的参数。
我们将这段代码保存为test.py,若通过以下命令执行它:python test.py -c config1 -h --help --config=config1 param1 param2
结果会是:
['-c', 'test', '-h', '--help', '--config=test2', 'param1', 'param2']
[('-c', 'test'), ('-h', ''), ('--help', ''), ('--config', 'test2')]
Using configeration file test
help information
help information
Using configeration file test2
['param1', 'param2']
我们可以看到,getopt函数成功获取了所有-c, --config, -h, --help等配置选项,并成功获取了参数param1, param2
那么,如果我们把换一种执行程序的方式会怎么样呢?
python test.py -c config1 param1 param2 -h --help --config=config1
执行结果会是:
['-c', 'test', 'param1', 'param2', '-h', '--help', '--config=test2']
[('-c', 'test')]
Using configeration file test
['param1', 'param2', '-h', '--help', '--config=test2']
我们发现,仅-c指定的配置选项被解析出来了,而剩下的都被当做了一般的参数,这就是getopt的缺陷。
这时候,gnu_opt的优势就体现出来了,我们如果把代码中的getot函数换作gnu_getopt,就会得到正常的结果:
['-c', 'test', '-h', '--help', '--config=test2', 'param1', 'param2']
[('-c', 'test'), ('-h', ''), ('--help', ''), ('--config', 'test2')]
Using configeration file test
help information
help information
Using configeration file test2
['param1', 'param2']
从以上例子,可以总结出getopt和gnu_getopt的不同:
getopt函数一旦遇到第一个不符合配置选项格式的参数就放弃解析了,剩下的部分不检查。所以,当使用它时,为了保证程序的运行,一般的参数一定要放在最后面。
gnu_getopt函数则可以轻松面对这个问题,允许用户随便放置一般参数的位置