JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » 交流、聊天、灌水 » 巨蟒咬人啦∼  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友   
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 【Python】[分享] Python optparse package (2) [精華]
dummycat





發文: 9
於 2005-01-13 23:53 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
替 option 分門別類:

如果能夠在 help 訊息中,將性質相近的 option 放在一起,與其它 option 明顯區別開來,相信使用者在閱讀時,就能夠很快地查到所要的資訊了。 optparse 套件提供了將 option 以 group 分開的機制:
1
2
3
4
5
  group = OptionGroup(parser, "Dangerous Options",
                        "Caution: use these options at your own risk.  "
                        "It is believed that some of them bite.")
    group.add_option("-g", action="store_true", help="Group option.")
    parser.add_option_group(group)

首先產生一個 OptionGroup 物件,將 OptionParser 和 help 訊息當做參數交給建構子,然後呼叫 OptionGroup.add_option() 加入 option,最後再呼叫 OptionParser.add_option_group() 加入此 group。如此 help 訊息中的 option 就會按 group 顯示了!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  usage:  [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'
    
      Dangerous Options:
        Caution: use of these options is at your own risk.  It is believed that
        some of them bite.
        -g                 Group option.

顯示程式版本:

無論是 GUI 或是 CUI 程式,使用者都會關心目前的程式版本資訊。 optparse 套件也提供了版本資訊的支援:
1
parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")

在 OptionParser 建構時指定 version 參數,並將提供版本訊息(先前提到的 "%prot" 關鍵字亦可用在此處)。當使用者下達的命令中帶有參數 "---version" (只有 "-v" 不行)時,程式會顯示版本資訊:
1
2
  $/usr/bin/foo --version
    foo 1.0

指定讀入 option argument 的個數:

add_option() 有一個參數 nargs,用以指定該 option 會從命令列上讀入幾個 option argument。舉例來說,如果 add_option(..., narg = 3, ...):
1
    $myprog --file w x y z

則 opts.file 將會是一個 tuple,內容為 ('w', 'z', 'y')。如果 option argument 個數不足,程式會回應錯誤訊息。

type of an option:

在加入 option 時,參數 type 代表該 option 儲存 dest 的型態。支援的型態有 string, int, long, choice, float 和 complex。若要加入其它型態,請參考 Python Library Reference 6.20.5 小節,"Extending optparse"。
對於 string 型態的 option, option argument 會被直接將結果存入 dest。

對於 int, long, float 和 complex 型態, option argument 會被轉換成相對應的型別;如果轉換的過程失敗,例如原本預期收到一個 int,卻收到一個字串,程式會結束並列印錯誤訊息。

對於 choice 型態, 在呼叫 OptionParser.add_option() 要指定一個由字串所組成的 tuple 或 list 給 choice 參數,接著 OptionParser.check_choice() 會比對傳入的 option argument 是否和 choice tuple 或 choice list 相同,若不相同則會丟出 OptionValueError。

action of an option:

在加入 option 時,參數 action 代表對 option argument 所要進行的動作。參數 action 有下列幾種:
<ul>
<li>store : 預設的 action,將 option argument 存到指定的 dest。</li>
<li>store_const : 將 dest 的值設為一個給定的常數。</li>
1
2
3
4
5
6
    make_option("-q", "--quiet",
       action="store_const", const=0, dest="verbose"),
    make_option("-v", "--verbose",
           action="store_const", const=1, dest="verbose"),
    make_option("--noisy",
           action="store_const", const=2, dest="verbose"),

當 "--noisy" 出現時, opts.verbose 的值將會被設定成 2。<br>
</li>
<li>store_true : 將 dest 的值設定為 True。<br></li>
<li>store_false : 將 dest 的值設定為 False。<br></li>
<li>append : 將 option argument 增加到 dest 中,而 dest 的型態將會是 list。使用 append action 時,命令列中可以重覆出現 option 和 option argument:
1
    $myprog -f 1 -f 2 -f 3

則 opts.optargs 將會是 ['1', '2', '3']。如果是 store action,那麼 opts.optargs 將只會是 3,因為每指定一次 option, dest 的值就一直被更新。

若呼叫 add_option() 時參數 nargs 被設定,而 action = append 時,程式可以接受下列命令列參數:
1
2
3
4
5
6
7
8
9
10
    parser.add_option(dest = "optargs",
                      action = "append",
                      nargs = 3)
    ...
    print opts.optargs
 
    -----------------------------
    
    $myprog -f 1 2 3 -f 4 5 6 -f 7 8 9
    [('1', '2', '3'), ('4', '5', '6'), ('7', '8', '9')]

看出其中差異了嗎? nargs 會將 option argument 包裝成 tuple,而 append 參數會將包裝好的 tuple 再"附加"到原有的 list 中。</li>
<li>count : 將 dest 的值加 1。 dest 的值會被初始會 0,該 option 每出現一次, dest 的值就增加 1。<br></li>
<li>callback : 請參考 Python Library Reference 6.20.4。<br></li>
<li>help : 列印 help 訊息。<br></li>
<li>version : 列印程式版本。<br></li>
</ul>

錯誤處置:
如果 option 預期會收到一個 int,而使用者傳入的是 string 參數時,會發生什麼事?
1
2
3
    optParser.add_option("-n",
                         dest = "theNumber",
                         type = "int")

若使用者輸入的命令是:
1
    $ /usr/bin/foo -n abc

程式會發出錯誤訊息,並告知使用者輸入的參數有誤,並且以非零的回傳值結束:
1
2
3
    usage: foo[ -n <theNumber>]
    
    foo: error: option -n: invalid integer value: 'abc'

OptionParser 的一些操作方法:

在加入 option 或解讀完參數之後,可以透過 OptionParser 的一些方法來得到一些資訊(以下的 opt_str 就是 "-f", "--file" 這些在增加 option 時所用到的參數):

<UL>
<LI>has_option(opt_str) : 檢查 OptionParser 中是否有某個 option。</LI>
<LI>get_option(opt_str) : 取得 OptionParser 中的某個 option。</LI>
<LI>remove_option(opt_str) : 刪除 OptionParser 中的某個 option。</LI>
</UL>

當 option 發生碰撞(重覆)時:

option 以下列的方式加入時:
1
2
3
    parser.add_option("-n", "--dry-run", ...)
    ...
    parser.add_option("-n", "--noisy", ...)

就稱為"碰撞"。當 option 碰撞時, optparse 會丟出 OptionConflictError。程式設計師應該在設計期就解決掉這個問題,也就是說,不應該使用 try - except 來捕捉這個錯誤 - 畢竟這在設計期就可以被處理掉的。

當 OptionParser 的被繼承時,一些標準的 option 就很有可能被子類別覆蓋掉。這種情況下,可以設定 OptionParse 處置碰撞的方式:
1
2
3
    parser.set_conflict_handler("resolve")
    or
    parser = OptionParser(..., conflict_handler="resolve")

都可以讓後來加入的 option 覆蓋掉原有的 option。預設的 conflict_handler 值為 "error",也就是直接丟出 OptionConflictError。所謂覆蓋,也不是直接移除掉原有的 option,而是避開後來加入的 option:
1
2
3
4
5
    parser = OptionParser(conflict_handler="resolve")
    
    parser.add_option("-n", "--dry-run", ..., help="original dry-run option")
    ...
    parser.add_option("-n", "--noisy", ..., help="be noisy")

在 help 訊息中,就會看到:
1
2
3
4
    options:
      --dry-run     original dry-run option
      ...
      -n, --noisy   be noisy

第一個 option 的 "-n" 被刪去了。如果這時又加入一個 option,使用了 "--dry-run"做為名稱呢?那麼第一個 option 就會直接被移除,因為它已經完全被覆蓋掉了,程式將不認得它, help 訊息中也不會有它的蹤跡。

在這裡我省略了 Callback option 和 Extending optparse 兩個小節,如果有興趣,可以親閱 Python Library Reference;對於這篇文章若有疑問的,也可以先找找 Reference,也許我漏掉了也說不定。

程式寫得愈多,愈覺得自己的渺小。這些設計精良的套件,若不是當初由許多無私的前輩們開發出來,我們又怎麼夠享受到它的便利性?以上是我參考 Python Library Reference, 6.19 optparse 介紹的內容,所寫的心得筆記。希望對這裡的 Python 同好有幫助,如果有錯誤也請多指正!


dummycat edited on 2005-01-13 23:58
reply to postreply to post
» JWorld@TW »  交流、聊天、灌水 » 巨蟒咬人啦∼

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8