15.3. getopt — 解析命令行参数
目的:命令行选项语法解析
 getopt 模块是原始的命令行选项语法解析器,它支持所有由Unix函数 getopt 建立的惯例。它能解析一串参数序列,例如 sys.argv 并返回包含(选项,参数)对的元组和非选项参数的序列。
可支持的选项语法包括长和短两种形式的选项:
-a
-bval
-b val
--noarg
--witharg=val
--witharg val
注释
getopt并没有被弃用,但是argparse的维护更加活跃,应当被用于新的开发项目上。
函数参数
 getopt() 函数有以下三个参数:
- 第一个参数是被解析的序列。它通常来自于 sys.argv[1:](忽略了位于sys.arg[0]位置上的程序名)。
- 第二个参数是对单字符选项的定义字符串。如果其中一个选项需要参数,其代表字符后会有一个冒号。
- 第三个参数,如果用到的话,则是长类型选项名序列。长类型选项往往多于一个字符表示,如 --noarg或--witharg。在该序列内的选项名应当不包括--前缀。如果长选项需要后跟参数,选项名后将有一个=后缀。
长和短形式的选项将在单次调用后被合并。
短选项
此示例程序接受三个选项。-a 是一个普通的标识符,而 -b 和 -c 需要一个参数。选项定义字符串为 "ab:c:"。
- 在选项定义字符串中,不需要前导符号 -;
- 需要参数的选项,在选项定义字符串后需要添加后缀 :。
getopt_short.py
import getopt
opts, args = getopt.getopt(['-a', '-bval', '-c', 'val'], 'ab:c:')
for opt in opts:
    print(opt)
此程序传递一个模拟的选项值列表给 getopt() 函数来展示它是如何处理的。以下为结果:
- 上例中的 opts变量接受了一个返回的列表;
- opts中的每一个元素都是- (选项, 参数)形式的元组。
- args参数本应接受一个由处理后剩余的参数组成的列表,本例中则为一个空列表。
$ python3 getopt_short.py
('-a', '')
('-b', 'val')
('-c', 'val')
长选项格式
对于具有两个选项 --noarg 和 --witharg 的程序,长选项定义语句应该为 [ 'noarg', 'witharg=' ]。
- 无参数选项定义字符串不需带有前导符号 --
- 需要参数的长选项,在定义时需要跟后缀等号 =
getopt_long.py
import getopt
opts, args = getopt.getopt(
    ['--noarg',             # 无参数选项
     '--witharg', 'val',    # 带参数选项
     '--witharg2=another'], # 也可用等号连接选项与参数
    '',
    ['noarg', 'witharg=', 'witharg2='],
)
for opt in opts:
    print(opt)
因为此示例中没有使用短格式的选项,因此 getopt() 函数的第二个返回值 args 为空。
$ python3 getopt_long.py
('--noarg', '')
('--witharg', 'val')
('--witharg2', 'another')
一个完整的例子
此示例是一个更加完整的程序,它带有五个选项:-o,-v,--output,--verbose,--version。
-o,--output,和 --version都需要一个参数。
getopt_example.py
import getopt
import sys
version = '1.0'
verbose = False
output_filename = 'default.out'
print('ARGV      :', sys.argv[1:])
try:
    options, remainder = getopt.getopt(
# 这里将解析后的选项-参数对存入变量 options 了,勿与后文的 opt,arg 混淆
        sys.argv[1:],
        'o:v',
        ['output=',
         'verbose',
         'version=',
         ])
except getopt.GetoptError as err:
    print('ERROR:', err)
    sys.exit(1)
print('OPTIONS   :', options)
for opt, arg in options: 
# arg 是此选项对应的参数, 不要与上文的 remainder 混淆
    if opt in ('-o', '--output'):
        output_filename = arg
    elif opt in ('-v', '--verbose'):
        verbose = True
    elif opt == '--version':
        version = arg
print('VERSION   :', version)
print('VERBOSE   :', verbose)
print('OUTPUT    :', output_filename)
print('REMAINING :', remainder)
此程序可以通过多种方式被调用。当不带参数地调用它时, 将会使用默认的设置。
$ python3 getopt_example.py
ARGV      : []
OPTIONS   : []
VERSION   : 1.0
VERBOSE   : False
OUTPUT    : default.out
REMAINING : []
一个单字符选项与它的参数可以用空格分隔。
$ python3 getopt_example.py -o foo
ARGV      : ['-o', 'foo']      # 用空格分隔的 选项 参数
OPTIONS   : [('-o', 'foo')]
VERSION   : 1.0
VERBOSE   : False
OUTPUT    : foo
REMAINING : []
或者, 可以直接将单字符选项与其参数组合。
$ python3 getopt_example.py -ofoo
ARGV      : ['-ofoo']   # 直接连写的 选项参数
OPTIONS   : [('-o', 'foo')] # 依然成功解析
VERSION   : 1.0
VERBOSE   : False
OUTPUT    : foo
REMAINING : []
一个长格式的选项也可以用空格分隔其参数。
$ python3 getopt_example.py --output foo
ARGV      : ['--output', 'foo']
OPTIONS   : [('--output', 'foo')]
VERSION   : 1.0
VERBOSE   : False
OUTPUT    : foo
REMAINING : []
但当要组合一个长格式选项与其参数时,应当使用等号 = 分隔。
$ python3 getopt_example.py --output=foo
ARGV      : ['--output=foo']
OPTIONS   : [('--output', 'foo')]
VERSION   : 1.0
VERBOSE   : False
OUTPUT    : foo
REMAINING : []
缩写长格式选项
只要提供了唯一的前缀,长格式选项不必在命令行上完整地拼出。
$ python3 getopt_example.py --o foo # 这里可不是 -o 哦
ARGV      : ['--o', 'foo']
OPTIONS   : [('--output', 'foo')]
VERSION   : 1.0
VERBOSE   : False
OUTPUT    : foo
REMAINING : []
如果提供地前缀并不唯一,则会抛出异常。
$ python3 getopt_example.py --ver 2.0
# --version 与 --verbose 混淆
ARGV      : ['--ver', '2.0']
ERROR: option --ver not a unique prefix
GNU 风格的选项解析
通常地,一旦遇到第一个非选项参数,选项处理就会停止。
$ python3 getopt_example.py -v not_an_option --output foo
ARGV      : ['-v', 'not_an_option', '--output', 'foo']
OPTIONS   : [('-v', '')]
VERSION   : 1.0
VERBOSE   : True
OUTPUT    : default.out
REMAINING : ['not_an_option', '--output', 'foo']
为了在命令行以任意顺序混合选项与非选项,使用 gnu_getopt() 来代替 getopt() 。
getopt_gnu.py
import getopt
import sys
version = '1.0'
verbose = False
output_filename = 'default.out'
print('ARGV      :', sys.argv[1:])
try:
    options, remainder = getopt.gnu_getopt(
        sys.argv[1:],
        'o:v',
        ['output=',
         'verbose',
         'version=',
         ])
except getopt.GetoptError as err:
    print('ERROR:', err)
    sys.exit(1)
print('OPTIONS   :', options)
for opt, arg in options:
    if opt in ('-o', '--output'):
        output_filename = arg
    elif opt in ('-v', '--verbose'):
        verbose = True
    elif opt == '--version':
        version = arg
print('VERSION   :', version)
print('VERBOSE   :', verbose)
print('OUTPUT    :', output_filename)
print('REMAINING :', remainder)
在上一个示例中更改了函数调用后,两者的差异变得清楚了。
$ python3 getopt_gnu.py -v not_an_option --output foo
ARGV      : ['-v', 'not_an_option', '--output', 'foo']
OPTIONS   : [('-v', ''), ('--output', 'foo')]
VERSION   : 1.0
VERBOSE   : True
OUTPUT    : foo
REMAINING : ['not_an_option']
结束参数处理
如果 getopt() 在输入的参数中遇到 "--",它将停止将剩余的参数作为选项处理。此特性可用来传递格式上类似于选项的参数,例如以 - 符号开头的文件名。
$ python3 getopt_example.py -v -- --output foo
ARGV      : ['-v', '--', '--output', 'foo']
OPTIONS   : [('-v', '')]  # -- 本身不作为参数传递
VERSION   : 1.0
VERBOSE   : True
OUTPUT    : default.out
REMAINING : ['--output', 'foo']
# 之后的参数都将存入 getopt() 的第二个返回值参阅
- Standard library documentation for getopt
argparse-- 在更新的应用中,用argparse模块代替getopt。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
 
           Python 3 标准库实例教程
Python 3 标准库实例教程 
             
             关于 LearnKu
                关于 LearnKu
               
                     
                     
                     粤公网安备 44030502004330号
 粤公网安备 44030502004330号