getopt:和C中的getopt()等價。
optparse:2.7後已不推薦使用。
argparse:基於optparse的新庫。
docopt:根據文檔描述,自動生成。另外一份參考文檔:docopt。git
更詳細的內容可參考上述文檔。github
getopt
若對C的getopt()
函數不熟悉,或者傾向於使用較少的代碼,或者須要對幫助信息和錯誤信息有更高要求,以上狀況優先使用argparse
。
該模塊主要提供兩個函數,以及一個異常判斷。web
getopt.getopt(args, options[, long_options])args
是須要解析的列表,一般狀況下,是sys.argv[1:]
。options
是解析列表時使用的範式,若是某一項(單個字母)後面須要參數,則在此項後添加':'
。long_options
必須是字符串列表,字符串開頭的'--'
不能包括,若某一項後面須要參數,則在此項後添加'='
。可選型的參數是不支持long_options
的。是根據輸入是不是字符串列表中惟一一項的前綴來匹配的。
返回值分爲兩個部分。第一部分是(option, value)
格式的列表,第二部分是解析完後剩餘部分。面試
getopt.gnu_getopt(args, options[, long_options])
做用同上。
區別在於getopt()
一旦遇到未配置的選項,就會中止解析。而此函數使用GNU規則,即已配置的選項和未配置的選項是能夠混雜的。sql
exception getopt.GetoptError
當一個沒法識別的選項,或者一個必需要有參數傳入的選項未傳入參數時,拋出此異常。
exception getopt.errorGetoptError
的舊名,爲了向後兼容而保留。app
具體實例可參考文檔,不推薦使用。less
argparse
一個簡單例子:ide
1
2
3
4
5
6
7
8
9
|
import argparse
parser = argparse.ArgumentParser(description='Example with long option names')
parser.add_argument('--noarg', action="store_true", default=False)
parser.add_argument('--witharg', action="store", dest="witharg")
parser.add_argument('--witharg2', action="store", dest="witharg2", type=int)
print parser.parse_args(['--noarg', '--witharg', 'val', '--witharg2=3'])
|
在argparse中,最經常使用的就是上述三部分了:建立一個ArgumentParser
對象;使用add_argument()
方法來爲建立的ArgumentParser
對象添加argument的解析規則;最後調用parse_args()
來解析傳入的內容,依據的是第二步制定的規則,生成的是一個Namespace
對象,若未傳參數給parse_args()
,那麼默認從sys.argv
來獲取命令行入參。
class argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[],formatter_class=argparse.HelpFormatter, prefix_chars=’-‘, fromfile_prefix_chars=None, argument_default=None,conflict_handler=’error’, add_help=True)prog
:程序的名字,默認是argv[0]。若設置,則在幫助信息中,可使用%(prog)s
來做爲格式化的引用(修改一處全局受用)。usage
:幫助信息的usage字段,描述程序的各類用法,默認狀況下會依據add_argument()
來自動生成。description
:一個簡單描述程序主要幹啥以及怎麼用的字符段。位於usage字符段和optional arguments字符段之間。epilog
:optional 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/--help
option,默認爲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
的值爲True
或False
。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=None, namespace=None)
將args
轉換爲namespace
對象的一個值。默認狀況下,sys.argv賦值給args
,一個空的Namespace
對象會被建立。
解析時,會對傳入的參數進行檢查,若不符合要求就會報錯。
通常狀況下,會自動判斷傳入的值究竟是一個可選參數,仍是一個負數(都用’-‘開頭)。但有時位置參數的值必須是一個’-‘開頭的值,如'-f'
,那麼使用parser.parse_args(['--', '-f'])
,'--'
表明後續的全部傳入值都須要看作是位置參數。parse_args()
會返回填充好的Namespace
對象,若要將它變爲字典,可以使用Python自帶的vars()
。
1
2
3
4
|
vars(...)
vars([object]) -> dictionary
Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.
|
也可不使用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=None, description=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=None, namespace=None)只解析知道的部分。
ArgumentParser.convert_arg_line_to_args(arg_line)
ArgumentParser.exit(status=0, message=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 pattern
和Option descriptions
。只有符合格式的字符串纔會被識別並解析,其他字符串會被忽略。Usage pattern
舉例:
1
|
Usage: my_program.py [-hso FILE] [--quiet | --verbose] [INPUT ...]
|
Usage pattern是doc
的子字符串。開始於usage:
(大小寫不敏感),結束於一行空行。
位於usage:
以後的第一個單詞是程序的名字,能夠重複屢次進行不一樣pattern的定義。
1
2
3
4
|
"""
Usage: my_program.py FILE
my_program.py COUNT FILE
"""
|
每一個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
舉例:
1
2
3
4
5
|
-h --help show this
-s --sorted sorted output
-o FILE specify output file [default: ./test.txt]
--quiet print less text
--verbose print more text
|
此部分位於usage pattern下方,它能夠有三方面做用:定義同義的短option和長option;某個option是否須要傳入參數;某個option是否有默認參數。
規則以下:
每行定義一個option,必須以一個或兩個「-」開頭。
爲定義須要傳入的參數,能夠在對應的option後方加上一個字符串,二者以空格或「=」相隔,二者都是可行的,但推薦只使用一種風格。
1
2
|
-o FILE --output=FILE # without comma, with "=" sign
-i <file>, --input <file> # with comma, wihtout "=" sign
|
使用兩個空格來將option自己與它的描述想分隔(按照示例應該是至少兩個空格)。
1
2
3
4
5
|
--verbose More text. # BAD, will be treated as if verbose option had
# an argument "More", so use 2 spaces instead
-q Quit. # GOOD
-o FILE Output file. # GOOD
--stdout Use stdout. # GOOD, 2 spaces
|
在option對應的描述後方進行默認參數的設置,格式是[default:]
。
1
2
3
|
--coefficient=K The K coefficient [default: 2.95]
--output=FILE Output file [default: test.txt]
--directory=DIR Some directory [default: ./]
|
若某option是可重複的,則默認參數會以空格做爲分割符進行分割,生成一個字符串列表。不然,做爲一個字符串總體。
docopt不適用於大型多層次的命令行參數解析(例如git,可是官方給出了一個example)。同時它沒有對數據的校驗功能,沒法向用戶報錯。
使用try docopt可進行docopt在線命令行參數解析。
舉例
例題是:知道創宇面試題。
使用argparse:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import argparse
from argparse import ArgumentDefaultsHelpFormatter
parser = argparse.ArgumentParser(prog="Spider", description='Knownsec Interview Spider By Docopt.', formatter_class=ArgumentDefaultsHelpFormatter)
parser.add_argument('-u', dest='url', action='store', required=True, help='the url the spider begins with')
parser.add_argument('-d', dest='deep', action='store', required=True, type=int, help='the depth of spider')
parser.add_argument('-f', dest='logfile', action='store', default='spider.log', help='the name of logfile')
parser.add_argument('-l', dest='loglevel(1-5)', action='store', type=int, choices=range(1,6), default=1, help='the details level of the log, range 1 to 5')
parser.add_argument('--testself', dest='testself', action='store_true', help='the self test by this program')
parser.add_argument('--thread', dest='thread_number', action='store', type=int, default=10, help="the thread pool's capacity")
parser.add_argument('--dbfile', dest='dbfile_filepath', action='store', required=True, help='the sqlite3 file path')
parser.add_argument('--key', dest='keyword', action='store', help='the keyword to search in webpage')
print parser.parse_args()
|
輸出:
1
2
|
python argparse_demo.py -u 123.com -d 1 --dbfile 123.txt -f logfile -l 1 --testself --thread 2
Namespace(dbfile_filepath='123.txt', deep=1, keyword=None, logfile='logfile', loglevel(1-5)=1, testself=True, thread_number=2, url='123.com')
|
體會就是功能很強大,實現很方便。因此我傾向於使用它。
使用docopt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
"""
Knownsec Interview Spider By Docopt.
Usage:
docopt_demo.py -u <url> -d <deep> [-f <logfile>] [-l <loglevel>] [--testself] [--thread <number>] --dbfile <filepath> [--key=<keyword>]
docopt_demo.py -h | --help
docopt_demo.py --version
Options:
-h --help Show this screen.
--version Show version.
-u <url> the url the spider begins with
-d <deep> the depth of spider
-f <logfile> the name of logfile [default: spider.log]
-l <loglevel> the details level of the log, range 1 to 5 [default: 1]
--testself the self test by this program
--thread <number> the thread pool's capacity [default: 10]
--dbfile <filepath> the sqlite3 file path
--key=<keyword> the keyword to search in webpage
"""
from docopt import docopt
if __name__ == '__main__':
arguments = docopt(__doc__, version='Spider 1.0')
print arguments
|
輸出:
1
2
3
4
5
6
7
8
9
10
11
12
|
python docopt_demo.py -u 123.com -d 1 --dbfile 123.txt -f logfile -l 1 --testself --thread 2
{'--dbfile': '123.txt',
'--help': False,
'--key': None,
'--testself': True,
'--thread': '2',
'--version': False,
'-d': '1',
'-f': 'logfile',
'-l': '1',
'-u': '123.com'}
|
可見,若是選項不須要參數,則-h和–version這種沒有設置的會賦值爲False,而–testself會賦值爲True;對於須要參數的選項,若是沒有設置,如–key,會被賦值爲None,而有設置而且給出參數的,會賦值對應的參數,如–dbfile。
那麼,對於有設置可是沒有給出參數的呢,並不會拋出異常報錯,而是把Usage部分(有時加上Options部分)輸出,真是太不友好了,debug的時候真是坑爹啊。
另外,使用docopt時候須要注意__doc__
的用法,若是是寫函數的__doc__
,則在函數名之下開始寫,而一個模塊的則必須在開頭寫,也就是在import以前寫,不然__doc__ == None
。