getopt — C 風格的命令列選項解析器

原始碼: Lib/getopt.py

備註

此模組的功能被認為是完整的。在 optparse 模組中提供了此 API 的一種更具宣告性且可擴充套件的替代方案。命令列引數處理的進一步功能增強,可以作為第三方模組在 PyPI 上獲取,或者作為特性在 argparse 模組中提供。


此模組可幫助指令碼解析 sys.argv 中的命令列引數。它支援與 Unix getopt() 函式相同的約定(包括“-”和“--”形式引數的特殊含義)。類似於 GNU 軟體所支援的長選項也可以透過可選的第三個引數來使用。

不熟悉 Unix getopt() 函式的使用者應考慮改用 argparse 模組。熟悉 Unix getopt() 函式,但希望在編寫更少程式碼並獲得更好的幫助和錯誤資訊的同時實現等效行為的使用者,應考慮使用 optparse 模組。請參閱 選擇引數解析庫 獲取更多詳細資訊。

此模組提供了兩個函式和一個異常

getopt.getopt(args, shortopts, longopts=[])

解析命令列選項和引數列表。args 是要解析的引數列表,不包括對正在執行的程式的首個引用。通常,這意味著 sys.argv[1:]shortopts 是指令碼想要識別的選項字母字串,需要引數的選項後跟一個冒號(':'),接受可選引數的選項後跟兩個冒號('::');即與 Unix getopt() 使用的格式相同。

備註

與 GNU getopt() 不同,在一個非選項引數之後,所有後續的引數也都被視為非選項引數。這類似於非 GNU 的 Unix 系統的工作方式。

如果指定了 longopts,它必須是一個字串列表,其中包含應支援的長選項的名稱。選項名稱中不應包含前導的 '--' 字元。需要引數的長選項後面應跟一個等號('=')。接受可選引數的長選項後面應跟一個等號和一個問號('=?')。要只接受長選項,shortopts 應為空字串。只要命令列上的長選項提供了與某個可接受選項完全匹配的字首,就可以被識別。例如,如果 longopts['foo', 'frob'],那麼選項 --fo 將匹配為 --foo,但 --f 不會唯一匹配,因此會引發 GetoptError

返回值包含兩個元素:第一個是 (option, value) 對的列表;第二個是在選項列表被剝離後剩餘的程式引數列表(這是 args 的一個尾部切片)。每個返回的選項和值對中,第一個元素是選項,對於短選項,它帶有連字元字首(例如 '-x'),對於長選項,它帶有兩個連字元字首(例如 '--long-option'),第二個元素是選項的引數,如果選項沒有引數,則為空字串。列表中的選項出現的順序與它們被找到的順序相同,因此允許多次出現。長選項和短選項可以混合使用。

在 3.14 版本發生變更: 支援可選引數。

getopt.gnu_getopt(args, shortopts, longopts=[])

此函式的工作方式類似於 getopt(),但預設使用 GNU 風格的掃描模式。這意味著選項和非選項引數可以混合使用。getopt() 函式一旦遇到非選項引數,就會停止處理選項。

如果選項字串的第一個字元是 '+',或者如果環境變數 POSIXLY_CORRECT 被設定,那麼選項處理會在遇到非選項引數時立即停止。

如果選項字串的第一個字元是 '-',那麼後面跟著選項的非選項引數會被新增到一個選項-值對的列表中,該對的第一個元素是 None,第二個元素是非選項引數的列表。gnu_getopt() 結果的第二個元素是在最後一個選項之後的程式引數列表。

在 3.14 版本發生變更: 支援按順序返回混合的選項和非選項引數。

exception getopt.GetoptError

當在引數列表中發現無法識別的選項時,或者當需要引數的選項沒有得到引數時,會引發此異常。此異常的引數是一個字串,指明瞭錯誤的原因。對於長選項,給一個不需要引數的選項提供了引數也會引發此異常。屬性 msgopt 提供了錯誤訊息和相關的選項;如果沒有與異常相關的特定選項,opt 是一個空字串。

exception getopt.error

GetoptError 的別名;用於向後相容。

一個只使用 Unix 風格選項的例子

>>> import getopt
>>> args = '-a -b -cfoo -d bar a1 a2'.split()
>>> args
['-a', '-b', '-cfoo', '-d', 'bar', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'abc:d:')
>>> optlist
[('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')]
>>> args
['a1', 'a2']

使用長選項名同樣簡單

>>> s = '--condition=foo --testing --output-file abc.def -x a1 a2'
>>> args = s.split()
>>> args
['--condition=foo', '--testing', '--output-file', 'abc.def', '-x', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'x', [
...     'condition=', 'output-file=', 'testing'])
>>> optlist
[('--condition', 'foo'), ('--testing', ''), ('--output-file', 'abc.def'), ('-x', '')]
>>> args
['a1', 'a2']

可選引數應被顯式地指定

>>> s = '-Con -C --color=off --color a1 a2'
>>> args = s.split()
>>> args
['-Con', '-C', '--color=off', '--color', 'a1', 'a2']
>>> optlist, args = getopt.getopt(args, 'C::', ['color=?'])
>>> optlist
[('-C', 'on'), ('-C', ''), ('--color', 'off'), ('--color', '')]
>>> args
['a1', 'a2']

可以保留選項和非選項引數的順序

>>> s = 'a1 -x a2 a3 a4 --long a5 a6'
>>> args = s.split()
>>> args
['a1', '-x', 'a2', 'a3', 'a4', '--long', 'a5', 'a6']
>>> optlist, args = getopt.gnu_getopt(args, '-x:', ['long='])
>>> optlist
[(None, ['a1']), ('-x', 'a2'), (None, ['a3', 'a4']), ('--long', 'a5')]
>>> args
['a6']

在指令碼中,典型的用法是這樣的

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError as err:
        # print help information and exit:
        print(err)  # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        elif o in ("-h", "--help"):
            usage()
            sys.exit()
        elif o in ("-o", "--output"):
            output = a
        else:
            assert False, "unhandled option"
    process(args, output=output, verbose=verbose)

if __name__ == "__main__":
    main()

請注意,使用 optparse 模組可以用更少的程式碼和更具資訊性的幫助和錯誤訊息來生成等效的命令列介面

import optparse

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option('-o', '--output')
    parser.add_option('-v', dest='verbose', action='store_true')
    opts, args = parser.parse_args()
    process(args, output=opts.output, verbose=opts.verbose)

對於這種情況,使用 argparse 模組也可以生成一個大致等效的命令列介面

import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--output')
    parser.add_argument('-v', dest='verbose', action='store_true')
    parser.add_argument('rest', nargs='*')
    args = parser.parse_args()
    process(args.rest, output=args.output, verbose=args.verbose)

請參閱 選擇引數解析庫 以瞭解此程式碼的 argparse 版本在行為上與 optparse(和 getopt)版本的不同之處。

參見

模組 optparse

宣告式的命令列選項解析。

模組 argparse

更具主見的命令列選項和引數解析庫。