python 解析命令行

原文 http://python.jobbole.com/87014html

 

python解析命令行

getopt:和C中的getopt()等價。
optparse:2.7後已不推薦使用。
argparse:基於optparse的新庫。
docopt:根據文檔描述,自動生成。另外一份參考文檔:docoptgit

更詳細的內容可參考上述文檔。github

getopt


若對C的getopt()函數不熟悉,或者傾向於使用較少的代碼,或者須要對幫助信息和錯誤信息有更高要求,以上狀況優先使用argparse
該模塊主要提供兩個函數,以及一個異常判斷。web

getopt.getopt(argsoptions[, long_options])
args是須要解析的列表,一般狀況下,是sys.argv[1:]
options是解析列表時使用的範式,若是某一項(單個字母)後面須要參數,則在此項後添加':'
long_options必須是字符串列表,字符串開頭的'--'不能包括,若某一項後面須要參數,則在此項後添加'='。可選型的參數是不支持long_options的。是根據輸入是不是字符串列表中惟一一項的前綴來匹配的。
返回值分爲兩個部分。第一部分是(option, value)格式的列表,第二部分是解析完後剩餘部分。面試

getopt.gnu_getopt(argsoptions[, long_options])
做用同上。
區別在於getopt()一旦遇到未配置的選項,就會中止解析。而此函數使用GNU規則,即已配置的選項和未配置的選項是能夠混雜的。sql

exception getopt.GetoptError
當一個沒法識別的選項,或者一個必需要有參數傳入的選項未傳入參數時,拋出此異常。
exception getopt.error
GetoptError的舊名,爲了向後兼容而保留。app

具體實例可參考文檔,不推薦使用。less

argparse


一個簡單例子:ide

argparse中,最經常使用的就是上述三部分了:建立一個ArgumentParser對象;使用add_argument()方法來爲建立的ArgumentParser對象添加argument的解析規則;最後調用parse_args()來解析傳入的內容,依據的是第二步制定的規則,生成的是一個Namespace對象,若未傳參數給parse_args(),那麼默認從sys.argv來獲取命令行入參。

class argparse.ArgumentParser(prog=Noneusage=Nonedescription=Noneepilog=Noneparents=[],formatter_class=argparse.HelpFormatterprefix_chars=’-‘fromfile_prefix_chars=Noneargument_default=None,conflict_handler=’error’add_help=True)
prog:程序的名字,默認是argv[0]。若設置,則在幫助信息中,可使用%(prog)s來做爲格式化的引用(修改一處全局受用)。
usage:幫助信息的usage字段,描述程序的各類用法,默認狀況下會依據add_argument()來自動生成。
description:一個簡單描述程序主要幹啥以及怎麼用的字符段。位於usage字符段和optional arguments字符段之間。
epilogoptional arguments字符段以後的字符段。
parents:繼承的父parser,爲了不一些公共的內容重複定義,父parser在初始化時會設置add_help=False,這是爲了防止出現父與子parser的-h衝突而拋出異常。
formatter_class:對於help輸出進行格式化,除了輸出的樣式外,若是設置爲ArgumentDefaultsHelpFormatter,則會自動在help輸出中添加已定義的default值。
prefix_chars:options前的字符,默認爲’-‘,能夠添加其餘字符,如’-+’,可是若是沒有包括’-‘,那麼對應的option如’-h’就沒法解析。
fromfile_prefix_chars:有時會使用文件給parse_args()傳入參數,爲了可以識別文件字符串,如」demo.txt」,須要設置此值,如」@」,那麼全部以此字符爲開頭的字符串都被看成是文件,因此傳給parse_args()的參數應該是@demo.txt。在該文件中,一行只能有一個參數。如文件中的'-f\nbar'會被解析成['-f','bar']
argument_default:通常狀況下,默認值使用add_argument()來添加,或者使用set_defaults()設置一些鍵值對來添加。剩下一種狀況就是設置此項(此處沒看明白是咋回事)。
conflict_handler:解決在add_argument()階段有衝突的option的依據策略,默認爲error即拋出異常。通常狀況下遇到衝突是拋出異常便可,可是若是設置了parents,那麼須要重寫父parser中的規則的時候,就須要將此項設置爲resolve,可是重寫是精確匹配的,如老規則定義了-h/--help,重寫了-h,那麼--help仍是老規則。
add_help:是否添加-h/--helpoption,默認爲True。爲False時,是要作parent(其實能夠設置子Parser重寫)。默認是-h/--help,若prefix_chars中沒有包含’-‘,那麼就以其中第一個字符做爲代替。

ArgumentParser.add_argument(name or flags…[, action][, nargs][, const][, default][, type][, choices][, required][, help][,metavar][, dest])
name or flags:是位置參數,則須要傳入名字;要是可選參數,則須要進行定義,如’-f’,’–foo’。
action:定義傳入的參數如何處理。

  • action='store',默認取值,保存傳入參數。
  • action='store_const',須要添加const,意味着該argument的值不從命令行輸入,而是取const的值。
  • action='store_true' or action='store_false''store_const'的特殊情形,意味着const的值爲TrueFalse
  • action='append',表示傳入的值會做爲一個列表的一項,意味着option能夠在命令行中屢次出現。
  • action='append_const',傳入列表的項由const定義,一般用在須要多個argument將值傳入一個列表中的場景。
  • action='count',輸出argument出現的次數。
  • action='help',已默認添加。
  • action='version',須要定義version,使用時輸出版本信息並退出。
  • 自定義,經過定義一個argparse.Action子類來實現。實際上,上面的這些可選項都是經過這種形式定義的。

nargs:一般一個選項後跟一個參數,經過設置此項能夠實現不一樣狀況。

  • nargs=N,一個選項後能夠跟多個參數(action='append'時,依然是一個選項後跟一個參數,只不過選項能夠屢次出現),參數的個數必須爲N的值,這些參數會生成一個列表,當nargs=1時,會生成一個長度爲1的列表。
  • nargs=?,若是沒有在命令行中出現對應的項,則給對應的項賦值爲default。特殊的是,對於可選項,若是命令行中出現了此可選項,可是以後沒有跟隨賦值參數,則此時給此可選項並非賦值default的值,而是賦值const的值。
  • nargs=*,和N相似,可是沒有規定列表長度。
  • nargs=+,和*相似,可是給對應的項當沒有傳入參數時,會報錯error: too few arguments
  • nargs=argparse.REMAINDER,全部剩餘的參數,均轉化爲一個列表賦值給此項,一般用此方法來將剩餘的參數傳入另外一個parser進行解析。

若是nargs沒有定義,則可傳入參數的數量由action決定,一般狀況下爲一個,而且不會生成長度爲一的列表。
const,一種是定義action='store_const'action='append_const'時使用。一種是定義nargs='?'時,可選項出如今命令行中,但以後並無跟隨賦值的參數,做爲默認值傳給此可選項。
default:默認值。
若是是一個字符串,那麼Parser解析的時候會將它做爲命令行傳入值,使用type的值來進行轉換類型,可是若是不是的話,就會使用定義的值而不進行類型轉換。
若是設置了nargs='?'nargs='*',那麼當沒有參數賦值給該項時,會使用default定義的值。
default=argparse.SUPPRESS時,則表示命令行中未出現某一項時,不會對它進行默認賦值。
type:用於類型檢查和類型轉換。
使用FileType可簡化對文件的操做。
還能夠自定義函數,輸入是一個字符串,輸出是轉換後的字符串。
當設置choices的時,類型檢查會變得容易,由於只須要在一個範圍內比較便可。
choices:給定了取值範圍,超出會報錯。
type也有定義時,會先使用type進行類型檢查,因此choices中的取值必須符合type的定義,不然在parse_args()時會報錯。
任何支持in操做符的都可做爲choices的賦值,因此字典,列表,集合,等等其餘容器均都支持。
required:默認狀況下,可選項(前面有'-')被認爲並不必定須要出如今命令行參數中,可是若是設置了required=True的話,則必須出現。此類設置違揹人的常識,應避免使用。
help:幫助信息。
以前提到的%(prog)s可用於此處程序名的格式化,此外,還有%(default)s格式化default的值,%(type)s格式化type的值。
設置爲argparse.SUPPRESS可不顯示幫助信息。
metavar:在Parser生成幫助信息時,須要有字符表明須要傳入的值。(這一段和dest相同,使用的就是dest的值)若是是位置參數,則用它自己代替;若是是可選參數,則使用它的大寫來代替。使用metavar可替換默認的字符。
dest:大部分的選項都須要經過命令行來給其賦值,這些值的名字經過dest來定義,默認的規則如同metavar中所述。

ArgumentParser.parse_args(args=Nonenamespace=None)
args轉換爲namespace對象的一個值。默認狀況下,sys.argv賦值給args,一個空的Namespace對象會被建立。
解析時,會對傳入的參數進行檢查,若不符合要求就會報錯。
通常狀況下,會自動判斷傳入的值究竟是一個可選參數,仍是一個負數(都用’-‘開頭)。但有時位置參數的值必須是一個’-‘開頭的值,如'-f',那麼使用parser.parse_args(['--', '-f'])'--'表明後續的全部傳入值都須要看作是位置參數。
parse_args()會返回填充好的Namespace對象,若要將它變爲字典,可以使用Python自帶的vars()

也可不使用Namespace,而是傳入一個提早生成的對象。

其餘
ArgumentParser.add_subparsers([title][, description][, prog][, parser_class][, action][, option_string][, dest][, help][, metavar])用來定義子Parser。
class argparse.FileType(mode=’r’bufsize=None)用來給add_argument()中的type參數賦值。
ArgumentParser.add_argument_group(title=Nonedescription=None)定義一個組。
ArgumentParser.add_mutually_exclusive_group(required=False)定義組中只能有一個選項出現。
ArgumentParser.set_defaults(kwargs)設置默認值。
ArgumentParser.get_default(dest)獲取默認值。
ArgumentParser.print_usage(file=None)
ArgumentParser.print_help(file=None)
ArgumentParser.format_usage()
ArgumentParser.format_help()以上四種都是幫助信息相關的。
ArgumentParser.parse_known_args(args=Nonenamespace=None)只解析知道的部分。
ArgumentParser.convert_arg_line_to_args(arg_line)
ArgumentParser.exit(status=0message=None)
ArgumentParser.error(message)

docopt


理念是好的幫助信息應該正好包含生成命令行解析器所須要的所有信息。

docopt.docopt(doc, argv=None, help=True, version=None, options_first=False)
doc參數能夠是一個模塊的docstring(__doc__),或者是其餘符合格式的幫助信息。
argv默認狀況下使用sys.argv[1:],或者可使用一個字符串。
help默認爲True,當輸入-h--help後(需提早設置好),解析器可以自動生成對應的幫助文本。須要手動管理的可設置爲False。
version版本信息,是可選參數。
options_first默認爲False。當設置爲True時,不容許可選參數和位置參數進行混合,即在出現的第一個位置參數以後的全部參數,均被看成是位置參數,這是爲了和POSIX保持兼容。
返回值是一個字典,key是option,value就是對應輸入的參數。

幫助信息格式分爲兩部分,Usage patternOption descriptions。只有符合格式的字符串纔會被識別並解析,其他字符串會被忽略。
Usage pattern
舉例:

Usage pattern是doc的子字符串。開始於usage:(大小寫不敏感),結束於一行空行。
位於usage:以後的第一個單詞是程序的名字,能夠重複屢次進行不一樣pattern的定義。

每一個pattern都由如下部分組成。
一個是<arguments>, ARGUMENTS格式的定義,要麼是用尖括號包括,要麼是大寫。
還有一個是-options,必需要以「-」開頭,能夠堆棧好幾個option,如-oiv等價於-o -i -v。option是能夠有參數的,如-f FILE-f=FILE-fFILE,都是等價的。其餘一些選擇在下方的option descriptions中進行具體定義。
最後一個是commands,除了以上說起的兩種狀況,剩下的格式,再加上兩個特殊的命令:單個的「-」和雙個的「-」,這些都歸屬於此。

commands中,[ ]表示可選。( )表示必須存在,全部沒有用[ ]包裹的字符串都默認被( )包裹。
|是管道符,若某一個選項必須存在,則將他們用( )包裹,如my_program.py(--clockwise | --counter-clockwise) TIME,若都是可選項,則用[ ]包裹,如my_program.py[--left | --right]
表示有一個或多個元素,如my_program.py FILE ...表示一個或多個FILE可接受,而my_program.py [FILE ...]表示0個或多個FILE可接受。
[options](大小寫敏感)是任意options的縮寫。可使用它來定義該pattern可使用任何在下方Option descriptions中定義的option。
[–]是爲了分隔可選參數和位置參數,如Usage: my_program [options] [--] <file>...,其中中括號可去除,變爲必填項。
[-]若出現,則表示程序須要使用stdin,禁止使用file。而單個的則是一個普通字符。

若是在usage pattern中重複出現同名位置參數屢次,或者同名有參數的可選參數屢次,那麼傳入的值會被解析成一個列表。如Usage: my_program.py <file> <file> --path=<path>...的結果會是args['<file>'] == ['file1', 'file2']以及args['--path'] == ['./here', './there']

Option descriptions
舉例:

此部分位於usage pattern下方,它能夠有三方面做用:定義同義的短option和長option;某個option是否須要傳入參數;某個option是否有默認參數。
規則以下:
每行定義一個option,必須以一個或兩個「-」開頭。
爲定義須要傳入的參數,能夠在對應的option後方加上一個字符串,二者以空格或「=」相隔,二者都是可行的,但推薦只使用一種風格。

使用兩個空格來將option自己與它的描述想分隔(按照示例應該是至少兩個空格)。

在option對應的描述後方進行默認參數的設置,格式是[default:]

若某option是可重複的,則默認參數會以空格做爲分割符進行分割,生成一個字符串列表。不然,做爲一個字符串總體。

docopt不適用於大型多層次的命令行參數解析(例如git,可是官方給出了一個example)。同時它沒有對數據的校驗功能,沒法向用戶報錯。
使用try docopt可進行docopt在線命令行參數解析。

舉例


例題是:知道創宇面試題
使用argparse

輸出:

體會就是功能很強大,實現很方便。因此我傾向於使用它。

使用docopt

輸出:

可見,若是選項不須要參數,則-h和–version這種沒有設置的會賦值爲False,而–testself會賦值爲True;對於須要參數的選項,若是沒有設置,如–key,會被賦值爲None,而有設置而且給出參數的,會賦值對應的參數,如–dbfile。
那麼,對於有設置可是沒有給出參數的呢,並不會拋出異常報錯,而是把Usage部分(有時加上Options部分)輸出,真是太不友好了,debug的時候真是坑爹啊。

另外,使用docopt時候須要注意__doc__的用法,若是是寫函數的__doc__,則在函數名之下開始寫,而一個模塊的則必須在開頭寫,也就是在import以前寫,不然__doc__ == None

相關文章
相關標籤/搜索