转载于: http://koria.blog.hexun.com/15296722_d.html
 

簡介:

optparse 是一個能夠讓程式設計人員輕鬆設計出簡單明瞭、易於使用、符合標準的 Unix 命令列程式的 Python 套件。開始學習 Python 之後,我常常會寫一些小程式來處理日常的工作;漸漸地,我發現無法處理參數的程式的彈性有限,於是就開始為我的程式加上解讀命令列參數的功能。在發現這個套件之前,我總是覺得解讀命令列不難,但是要做到像標準 Unix 命令那樣完善的使用者互動和錯誤處置,可就不是一件簡單的事了!某天在 Python Library Reference 中發現這個套件,真是如獲至寶!從此不用再為解讀參數煩惱,可以更專注在解決問題上了!

如果對於 optparse 套件有興趣,想快速入門的話,可以直接看"基本使用流程"小節,然後再看後面的一些介紹與說明;當然啦!想獲得最詳細的資訊,就只有自己去看 Python Library Reference 囉~

就以下列命令來解釋一些術語,myprog 是命令的名字, $ 是命令列提示符號:

    $myprog -f thefile.txt -s xyz a1 a2 a3

●argument:
使用者在命令後面所輸入的字串。以本例來說,"-f", "thefile.txt", "-s", "xyz", "a1", "a2", "a3" 都是 argument。在 Python 中,可以使用 sys.argv[1:] 來得到命令列傳進來的 argument。為什麼是 sys.argv[1:] ,而不是 sys.argv 呢?因為命令列收到完整的參數還要加上一個命令本身的檔名,以本例來說, sys.argv 應該是:

    ["myprog", "-f", "thefile.txt", "-s", "xyz", "a1", "a2", "a3"]

所以如果要得到去除命令本身的檔名以後的參數列,就要靠 sys.argv[1:] 了。

●option:
一些傳遞給命令的額外 argument,以改變程式的行為。以本例來說, "-f", "-s" 就是 option。
有幾種 option 的寫法,在 Unix 系統上的傳統寫法是 "-" 後跟著一個字母,例如 "-f", "-s";以及 "-f -s", 和 "-fs", 在 Unix 系統上都可以被接受。 GNU project 使用另一種方式,以 "--" 後面跟著一串由 "-" 分開的字串,例如 "--file-for-log"。Python 的 optparse 套件只接受以上所提的兩種 option 格式。

顧名思義, option 應該是可有可無的,即使命令中沒有任何的 option,程式也應該能夠正確地執行。如果程式需要使用者輸入某些資料才能運作,那麼也應該是使用 positional argument 才對。

●option argument:
緊跟隨在 option 後的 argument,就是 option argument。以本例來說, "thefile.txt", "xyz" 都是 option argument。指定 option argument 有兩種寫法, "-f thefile" 和 "-fthefile", optparse 套件都接受。

option 亦可以沒有 option argument,意即 option 單獨存在。這樣的 option 通常做為旗標 (flag) 用,代表某個功能的開啟或是關閉。

●positional argument:
當一個 argument list 被解讀完後,剩下的就是 positional argument 了!以本例來說, "a1", "a2", "a3" 就是 positional argument。通常被用在"使用者必須輸入"的資訊上。

●required option:
一個有點讓人覺得矛盾的名詞:既然是 "option" (選擇),又怎麼會是 "required" (必須)的呢? optparse 套件不對這種 option 做出任何的限制或是協助。詳情可以參閱 Python Library Reference 6.20.5 的範例程式。

基本使用流程:

》1.產生一個 optparse.OptionParser 的物件。可以在產生時將"程式的命令列說明" (usage) 做為參數,交給 OptionParser 的建構子:

    from optparse import OptionParser
    MSG_USAGE = "myprog[ -f <filename>][ -s <xyz>] arg1[, arg2...]"
    optParser = OptionParser(MSG_USAGE)

》2.呼叫 OptionParser.add_option() 加入接受的 option: 

    optParser.add_option("-f", "--file", action = "store", type = "string", dest = "fileName")

參數 action 有許多種類,預設是 "store",所以即使省略也無妨,其它的 action 種類在下面會繼續說明。

若有一個以上的 option,重覆上述的方式加入(注意:以下省略了 action 參數): 


    optParser.add_option("-s", "--someopt", type = "string", dest = "someopt")

》3.呼叫 OptionParser.parse_args() 進行解讀。如果沒有傳入參數, OptionParser 預設會以 sys.argv[1:] 為對象進行解讀。OptionParser.parse_args() 會傳回一個 tuple,由 optparse.Values 和 一個 list 所組成。下例傳入一個假造的參數列: 

    fakeArgs = ['-f', 'thefile.txt', '-s', 'xyz', 'arg1', 'arg2', 'arge']
   
    options, args = optParser.parse_args(fakeArgs)
   
    print options.fileName
    print options.someopt
    print args

最後會得到的輸出結果: 

    thefile.txt
    xyz
    ['arg1', 'arg2', 'arge']

這是一個簡單的範例,說明了 OptionParser 的一般使用方式。透過這個例子,可以看到如果為程式加入 option, 並且在程式中取得 option argument 和 positional argument。OptionParser.parse_args() 還有許多用法,下面會說明一部份。

為程式加入 flag option:

許多的 Unix 命令擁有 "-v", "-q" 的 option,代表"提供詳細訊息"或是"不顯示訊息"。要做到這一點,只要在程式中加入下列的 option : 

    parser.add_option("-v", action="store_true", dest="verbose")
    parser.add_option("-q", action="store_false", dest="verbose")
    opts, args = parser.parse_args()

第一個 add_option() 加入了一個 "-v" 的 option;如果命令列參數中出現了 "-v",則 opts.verbose 將會是 True;相反的,第二個 add_option() 加入了一個 "-q" option;如果命令列參數中出現了 "-q",則 opts.verbose 將會是 False,這兩者並不相悖,程式可以設計成:當收到 "-v" 時,顯示詳細訊息;當收到 "-q" 時,顯示概略訊息,或完全不顯示;當兩者都沒有收到,則顯示一般的訊息。

設定 option 的預設值:

上述的例子都假設命令例會收到預期中的 option,那麼如果沒有 option 時,接收到的 option 值會是什麼呢?答案是 None!如果想為 option 提供預設值,只要在 OptionParser.parse_args()中指定參數 default 就行了: 

    parser.add_option("-v", action="store_true", dest="verbose", default = True)
    parser.add_option("-q", action="store_false", dest="verbose")
    opts, args = parser.parse_args()

上述的程式碼為程式加入了兩個 option,當 "-v" 沒有出現時, opts.verbose 預設值為 True;當 "-q" 被指定時, opts.verbose 被設定為 False,和上一個例子有點不同。再看下一個例子:

    parser.add_option("-v", action="store_true", dest="verbose", default=False)
    parser.add_option("-q", action="store_false", dest="verbose", default=True)

opts.verbose 的預設值會是什麼?答案是 True,最後一個指定到同一個目標的 option 預設值會被採用。

一般的 option 亦可加入預設值: 

    parser.add_option("-f", action="store", dest="fileName", default = "defaultConfig.txt")

為程式加入說明:

標準的 Unix 命令大多有著 "-h", "--help" 的 option,會將使用說明印出來。在 OptionParser.parse_args() 中指定 "help" 參數,並指定說明的字串,就可以為這個 option 加入說明了: 

    parser.add_option("-v", action="store_true", dest="verbose", default=False, 
help="make lots of noise [default]")

當程式收到 "-h" 或 "--help",交給 OptionParser 解讀時,會自動印出說明內容,而忽略其它的 argument: 

    usage: <yourscript> [options] arg1 arg2

    options:
      -h, --help           show this help message and exit
      -v, --verbose        make lots of noise [default]
      -q, --quiet          be vewwy quiet (I'm hunting wabbits)
      -fFILE, --file=FILE  write output to FILE
      -mMODE, --mode=MODE  interaction mode: one of 'novice', 'intermediate'
                           [default], 'expert'

還記得一開始提到交給 OptionParser 建構子的參數 MSG_USAGE 嗎? optparse 套件對 usage 訊息也提供了一些支援。在 usage 中使用 "%prog" 關鍵字, OptionParser 會自動將其代換為程式名,即 sys.args[0]: 

    usage = "usage: %prog [options] arg1 arg2"

如果程式名為 "myprog",則出現在 help 訊息中的 usage 就會是:

    usage = "usage: myprog [options] arg1 arg2"

如果OptionParser 建構子沒有收到任何參數,則會自動產生一個 usage 訊息:

    "usage: %prog [options]"

前提是程式沒有 positional argument。甭擔心 option 在 help 訊息中排列的方式, OptionParser 會搞定一切,如同前面程式所示。