2009-08-11 21 views
5

根據PEP 257,命令行腳本的文檔字符串應該是其使用消息。如何使用Python的optparse模塊符合PEP 257文檔?

當 腳本與不正確 或丟失參數調用(或也許 一個「腳本(一 獨立的程序)的文檔字符串應該是作爲其「使用」的消息,打印的可用 -h「選項,用於」幫助「)。這樣一個 文檔字符串應記錄腳本的 函數和命令行語法, 環境變量和文件。 用法消息可以是相當複雜的 (幾個屏幕全),並應 足以爲新用戶正常使用 命令,以及一個完整的 快速參考,所有 選項和參數的 複雜的用戶。

所以,我的文檔字符串會是這個樣子:

 
<tool name> <copyright info> 

Usage: <prog name> [options] [args] 

some text explaining the usage... 

Options: 
    -h, --help show this help message and exit 
    ... 

現在我想使用optparse模塊。 optparse生成的「選項」部分和「使用」解釋命令行語法:

from optparse import OptionParser 

if __name__ == "__main__": 
    parser = OptionParser() 
    (options, args) = parser.parse_args() 

所以調用帶「-H」標誌打印的腳本:

 
Usage: script.py [options] 

Options: 
    -h, --help show this help message and exit 

這可以被修改爲如下:

parser = OptionParser(usage="Usage: %prog [options] [args]", 
         description="some text explaining the usage...") 

這導致

 
Usage: script.py [options] [args] 

some text explaining the usage... 

Options: 
    -h, --help show this help message and exit 

但是我如何在這裏使用docstring?將文檔字符串作爲使用消息傳遞有兩個問題。

  1. optparse追加 「用法:」 到文檔字符串,如果它不符合 「用法:」 開始
  2. 佔位符 '%PROG' 必須在文檔字符串

結果

使用

根據答案,似乎沒有辦法重用optparse模塊預期的文檔字符串。所以剩下的選擇是手動解析文檔字符串並構造OptionParser。 (所以我會接受S.Loot的答案)

「Usage:」部分由IndentedHelpFormatter引入,它可以用OptionParser .__ init __()中的formatter參數替換。

回答

4

選擇1:複製並粘貼。不幹,但可行。

選擇2:解析自己的文檔字符串以去除描述段落。它總是第二段,所以你可以分成'\ n \ n'。

usage, description= __doc__.split('\n\n')[:2] 

由於optparse生成使用情況,您可能不希望提供使用的句子吧。您的使用版本我錯了。如果您堅持提供使用字符串optparse,我將把它作爲練習,讓讀者瞭解如何從usage字符串的前面刪除"Usage: "

+0

我喜歡第二個解決方案。不是很乾淨,但聰明而務實。 – 2009-08-11 13:49:26

+0

由於段落之間的空白行是RST標準,因此可以節省在__doc__上運行完整的Docutils分析,並根據定義獲取預期結果。 – 2009-08-11 14:24:58

+0

這可能是說明的一個選項。但我仍然無法重複使用'使用'部分,並且optparse強制使用「Usage:」開始。 – wierob 2009-08-11 17:00:45

1

我認爲我們必須對這個PEP的建議合理 - 我認爲將__doc__作爲總結長時間使用的簡短描述是可以的。但如果你是完美主義者:

'''<tool name> 

The full description and usage can be generated by optparse module. 

Description: ... 

''' 

... 

# Generate usage and options using optparse. 
usage, options = ... 

# Modify the docstring on the fly. 
docstring = __doc__.split('\n\n') 
docstring[1:2] = [__license__, usage, options] 
__doc__ = '\n\n'.join(docstring) 
6

我寫了一個模塊docopt做你想要什麼 - 在文檔字符串寫入使用情況的消息,並保持乾燥。 它還允許避免編寫繁瑣的OptionParser代碼,因爲docopt正根據用法消息生成解析器 。

檢查出來:http://github.com/docopt/docopt

"""Naval Fate. 

Usage: 
    naval_fate.py ship new <name>... 
    naval_fate.py ship [<name>] move <x> <y> [--speed=<kn>] 
    naval_fate.py ship shoot <x> <y> 
    naval_fate.py mine (set|remove) <x> <y> [--moored|--drifting] 
    naval_fate.py -h | --help 
    naval_fate.py --version 

Options: 
    -h --help  Show this screen. 
    --version  Show version. 
    --speed=<kn> Speed in knots [default: 10]. 
    --moored  Moored (anchored) mine. 
    --drifting Drifting mine. 

""" 
from docopt import docopt 


if __name__ == '__main__': 
    arguments = docopt(__doc__, version='Naval Fate 2.0') 
    print(arguments)