[python] argparse — 命令行選項、參數和子命令的解析器


 

15.4. argparse — 命令行選項、參數和子命令的解析器

版本2.7 中新引入。

源代碼: Lib/argparse.py

argparse模塊使得編寫用戶友好的命令行接口非常容易。程序只需定義好它要求的參數,然后argparse將負責如何從sys.argv中解析出這些參數。argparse模塊還會自動生成幫助和使用信息並且當用戶賦給程序非法的參數時產生錯誤信息。

 

15.4.1. 示例

下面的Python程序代碼接收一個整數序列並輸出它們的和或者最大值:

import argparse parser = argparse.ArgumentParser(description='Process some integers.') parser.add_argument('integers', metavar='N', type=int, nargs='+', help='an integer for the accumulator') parser.add_argument('--sum', dest='accumulate', action='store_const', const=sum, default=max, help='sum the integers (default: find the max)') args = parser.parse_args() print args.accumulate(args.integers) 

假設上面的Python代碼保存為一個叫做prog.py的文件,它可以在命令行上執行並提供有用的幫助信息:

$ python prog.py -h
usage: prog.py [-h] [--sum] N [N ...]

Process some integers.

positional arguments:
 N           an integer for the accumulator

optional arguments:
 -h, --help  show this help message and exit
 --sum       sum the integers (default: find the max)

當以適當的參數運行時,它打印出命令行整數的和或者最大值:

$ python prog.py 1 2 3 4
4

$ python prog.py 1 2 3 4 --sum
10

如果傳進非法的參數,它將產生錯誤信息:

$ python prog.py a b c
usage: prog.py [-h] [--sum] N [N ...]
prog.py: error: argument N: invalid int value: 'a'

下面的部分將帶你步步深入這個示例。

 

 

15.4.1.1. 創建一個解析器

使用argparse的第一步是創建一個ArgumentParser對象:

>>>
>>> parser = argparse.ArgumentParser(description='Process some integers.') 

ArgumentParser對象會保存把命令行解析成Python數據類型所需要的所有信息。

 

15.4.1.2. 添加參數

通過調用add_argument()方法向ArgumentParser添加程序的參數信息。通常情況下,這些信息告訴ArgumentParser如何接收命令行上的字符串並將它們轉換成對象。這些信息被保存下來並在調用parse_args()時用到。例如:

>>>
>>> parser.add_argument('integers', metavar='N', type=int, nargs='+', ... help='an integer for the accumulator') >>> parser.add_argument('--sum', dest='accumulate', action='store_const', ... const=sum, default=max, ... help='sum the integers (default: find the max)') 

接下來,調用parse_args()返回的對象將帶有兩個屬性,integersaccumulate屬性integers將是一個包含一個或多個整數的列表,如果命令行上指定 --sum,那么屬性accumulate將是sum()函數,如果沒有指定,則是max()函數。

15.4.1.3. 解析參數

ArgumentParser通過parse_args()方法解析參數。它將檢查命令行,把每個參數轉換成恰當的類型並采取恰當的動作。在大部分情況下,這意味着將從命令行中解析出來的屬性建立一個簡單的 Namespace對象。

>>>
>>> parser.parse_args(['--sum', '7', '-1', '42']) Namespace(accumulate=<built-in function sum>, integers=[7, -1, 42]) 

在腳本中,parse_args() 調用一般不帶參數,ArgumentParser 將根據sys.argv自動確定命令行參數。

 

15.4.2. ArgumentParser 對象

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)

創建一個新的ArgumentParser對象。所有的參數應該以關鍵字參數傳遞。下面有對每個參數各自詳細的描述,但是簡短地講它們是:

  • prog - 程序的名字(默認:sys.argv[0]
  • usage - 描述程序用法的字符串(默認:從解析器的參數生成)
  • description - 參數幫助信息之前的文本(默認:空)
  • epilog - 參數幫助信息之后的文本(默認:空)
  • parents - ArgumentParser 對象的一個列表,這些對象的參數應該包括進去
  • formatter_class - 定制化幫助信息的類
  • prefix_chars - 可選參數的前綴字符集(默認:‘-‘)
  • fromfile_prefix_chars - 額外的參數應該讀取的文件的前綴字符集(默認:None
  • argument_default - 參數的全局默認值(默認:None
  • conflict_handler - 解決沖突的可選參數的策略(通常沒有必要)
  • add_help - 給解析器添加-h/–help 選項(默認:True

下面的小節描述這些參數如何使用。

15.4.2.1. prog 參數

默認情況下,ArgumentParser對象使用sys.argv[0] 決定在幫助信息中如何顯示程序的名字。這個默認值幾乎總能滿足需求,因為幫助信息(中的程序名稱)會自動匹配命令行中調用的程序名稱。例如,參考下面這段myprogram.py文件中的代碼:

import argparse parser = argparse.ArgumentParser() parser.add_argument('--foo', help='foo help') args = parser.parse_args() 

該程序的幫助信息將顯示myprogram.py作為程序的名字(無論程序是在哪里被調用的):

$ python myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO   foo help
$ cd ..
$ python subdir\myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO   foo help

如果要改變這個默認的行為,可以使用prog=參數給ArgumentParser提供另外一個值:

>>>
>>> parser = argparse.ArgumentParser(prog='myprogram') >>> parser.print_help() usage: myprogram [-h] optional arguments:  -h, --help show this help message and exit 

注意,無論是來自sys.argv[0]還是來自prog=argument,在幫助信息中都可以使用%(prog)s格式符得到程序的名字。

>>>
>>> parser = argparse.ArgumentParser(prog='myprogram') >>> parser.add_argument('--foo', help='foo of the %(prog)s program') >>> parser.print_help() usage: myprogram [-h] [--foo FOO] optional arguments:  -h, --help show this help message and exit  --foo FOO foo of the myprogram program 

15.4.2.2. usage 參數

默認情況下,ArgumentParser依據它包含的參數計算出幫助信息:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--foo', nargs='?', help='foo help') >>> parser.add_argument('bar', nargs='+', help='bar help') >>> parser.print_help() usage: PROG [-h] [--foo [FOO]] bar [bar ...] positional arguments:  bar bar help optional arguments:  -h, --help show this help message and exit  --foo [FOO] foo help 

可以通過關鍵字參數usage=覆蓋默認的信息:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG', usage='%(prog)s [options]') >>> parser.add_argument('--foo', nargs='?', help='foo help') >>> parser.add_argument('bar', nargs='+', help='bar help') >>> parser.print_help() usage: PROG [options] positional arguments:  bar bar help optional arguments:  -h, --help show this help message and exit  --foo [FOO] foo help 

在你的幫助信息中,可以使用%(prog)s格式指示符替代程序的名字。

15.4.2.3. description 參數

ArgumentParser構造器的大部分調用都將使用description=關鍵字參數。這個參數給出程序做什么以及如何工作的簡短描述。在幫助信息中,該描述在命令行用法字符串和各個參數的幫助信息之間顯示:

>>>
>>> parser = argparse.ArgumentParser(description='A foo that bars') >>> parser.print_help() usage: argparse.py [-h] A foo that bars optional arguments:  -h, --help show this help message and exit 

默認情況下,該描述會換行以適應給定的空間。如果要改變這個行為,可以參見formatter_class參數。

15.4.2.4. epilog 參數

有些程序喜歡在參數的描述之后顯示額外的關於程序的描述。這些文本可以使用ArgumentParserepilog=參數指定:

>>>
>>> parser = argparse.ArgumentParser( ... description='A foo that bars', ... epilog="And that's how you'd foo a bar") >>> parser.print_help() usage: argparse.py [-h] A foo that bars optional arguments:  -h, --help show this help message and exit And that's how you'd foo a bar 

description一樣,epilog=文本默認會換行,但是可以通過ArgumentParserformatter_class參數調整這個行為。

15.4.2.5. parents 參數

有時候,幾個解析器會共享一個共同的參數集。可以使用一個帶有所有共享參數的解析器傳遞給ArgumentParserparents=參數,而不用重復定義這些參數。parents=參數接受一個ArgumentParser對象的列表,然后收集它們當中所有的位置參數和可選參數,並將這些參數添加到正在構建的ArgumentParser對象:

>>>
>>> parent_parser = argparse.ArgumentParser(add_help=False) >>> parent_parser.add_argument('--parent', type=int) >>> foo_parser = argparse.ArgumentParser(parents=[parent_parser]) >>> foo_parser.add_argument('foo') >>> foo_parser.parse_args(['--parent', '2', 'XXX']) Namespace(foo='XXX', parent=2) >>> bar_parser = argparse.ArgumentParser(parents=[parent_parser]) >>> bar_parser.add_argument('--bar') >>> bar_parser.parse_args(['--bar', 'YYY']) Namespace(bar='YYY', parent=None) 

注意大部分父解析器將指定add_help=False否則,ArgumentParser將看到兩個-h/--help 選項(一個在父解析器中,一個在子解析器中)並引發一個錯誤。

注意

 

在通過parents=傳遞父解析器之前,你必須完全初始化它們。如果在子解析器之后你改變了父解析器,這些改變不會反映在子解析器中。

15.4.2.6. formatter_class 參數

ArgumentParser對象允許通過指定一個格式化類來定制幫助信息的格式。當前,有三個種這樣的類:

class argparse.RawDescriptionHelpFormatter
class argparse.RawTextHelpFormatter
class argparse.ArgumentDefaultsHelpFormatter

前兩個在文本信息如何顯示上允許更多控制,最后一個會自動添加關於參數默認值的信息。

默認情況下,ArgumentParser對象會對命令行幫助信息中的descriptionepilog文本進行換行:

>>>
>>> parser = argparse.ArgumentParser( ... prog='PROG', ... description='''this description ...  was indented weird ...  but that is okay''', ... epilog=''' ...  likewise for this epilog whose whitespace will ...  be cleaned up and whose words will be wrapped ...  across a couple lines''') >>> parser.print_help() usage: PROG [-h] this description was indented weird but that is okay optional arguments:  -h, --help show this help message and exit likewise for this epilog whose whitespace will be cleaned up and whose words will be wrapped across a couple lines 

RawDescriptionHelpFormatter 傳遞給formatter_class= 表示description 和epilog 已經是正確的格式而不應該再折行:

>>>
>>> parser = argparse.ArgumentParser( ... prog='PROG', ... formatter_class=argparse.RawDescriptionHelpFormatter, ... description=textwrap.dedent('''\ ...  Please do not mess up this text! ...  -------------------------------- ...  I have indented it ...  exactly the way ...  I want it ...  ''')) >>> parser.print_help() usage: PROG [-h] Please do not mess up this text! --------------------------------  I have indented it  exactly the way  I want it optional arguments:  -h, --help show this help message and exit 

RawTextHelpFormatter 將保留所有幫助文本的空白,包括參數的描述。

另外一個格式化類ArgumentDefaultsHelpFormatter,將添加每個參數的默認值信息。

>>>
>>> parser = argparse.ArgumentParser( ... prog='PROG', ... formatter_class=argparse.ArgumentDefaultsHelpFormatter) >>> parser.add_argument('--foo', type=int, default=42, help='FOO!') >>> parser.add_argument('bar', nargs='*', default=[1, 2, 3], help='BAR!') >>> parser.print_help() usage: PROG [-h] [--foo FOO] [bar [bar ...]] positional arguments:  bar BAR! (default: [1, 2, 3]) optional arguments:  -h, --help show this help message and exit  --foo FOO FOO! (default: 42) 

15.4.2.7. prefix_chars 參數

大部分命令行選項使用-作為前綴,例如-f/--foo需要指出不同的或者額外的前綴字符的解析器,例如類似+f或者/foo這樣的選項,可以使用ArgumentParser構造器的prefix_chars=參數指定它們:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+') >>> parser.add_argument('+f') >>> parser.add_argument('++bar') >>> parser.parse_args('+f X ++bar Y'.split()) Namespace(bar='Y', f='X') 

prefix_chars=參數默認為'-'提供不包含-的字符集將導致不允許-f/--foo選項。

15.4.2.8. fromfile_prefix_chars 參數

有時候,例如處理一個特別長的參數列表的時候,把參數列表保存在文件中而不是在命令行中敲出來可能比較合理。如果給出ArgumentParser構造器的fromfile_prefix_chars=參數,那么以任意一個給定字符開始的參數將被當做文件,並且將被這些文件包含的參數替換。例如:

>>>
>>> with open('args.txt', 'w') as fp: ... fp.write('-f\nbar') >>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@') >>> parser.add_argument('-f') >>> parser.parse_args(['-f', 'foo', '@args.txt']) Namespace(f='bar') 

從文件中讀入的參數必須默認是每行一個參數(但另可參閱convert_arg_line_to_args())並且將被當做在命令行上原始文件所在的位置。所有在上面的例子中,表達式['-f', 'foo', '@args.txt'] 被認為等同於表達式['-f', 'foo', '-f', 'bar']

fromfile_prefix_chars= 參數默認為None,意味着參數永遠不會被當做文件。

15.4.2.9. argument_default 參數

通常情況下,參數默認值的指定通過傳遞一個默認值給add_argument()或者以一個指鍵-值對的集合調用set_defaults()方法。然而有時候,指定一個解析器范圍的參數默認值會比較有用。這可以通過傳遞argument_default=關鍵字參數給ArgumentParser完成。例如,為了全局地阻止parse_args() 調用時不必要的屬性創建,我們可以提供argument_default=SUPPRESS

>>>
>>> parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS) >>> parser.add_argument('--foo') >>> parser.add_argument('bar', nargs='?') >>> parser.parse_args(['--foo', '1', 'BAR']) Namespace(bar='BAR', foo='1') >>> parser.parse_args([]) Namespace() 

15.4.2.10. conflict_handler 參數

ArgumentParser對象不允許同一個選項具有兩個動作。默認情況下,如果試圖創建一個已經使用的選項,ArgumentParser對象將拋出異常。

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-f', '--foo', help='old foo help') >>> parser.add_argument('--foo', help='new foo help') Traceback (most recent call last):  .. ArgumentError: argument --foo: conflicting option string(s): --foo 

有時候(例如使用parents的時候)簡單地用相同的選項覆蓋舊的參數是有用的。為了得到這樣的行為,可以提供'resolve'值給ArgumentParserconflict_handler=參數:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve') >>> parser.add_argument('-f', '--foo', help='old foo help') >>> parser.add_argument('--foo', help='new foo help') >>> parser.print_help() usage: PROG [-h] [-f FOO] [--foo FOO] optional arguments:  -h, --help show this help message and exit  -f FOO old foo help  --foo FOO new foo help 

注意ArgumentParser 對象只有在所有的選項字符串被覆蓋時才刪除某個動作。所以,在上面的例子中,舊的-f/--foo動作依然保留為-f的動作,因為只有--foo選項字符串被覆蓋。

15.4.2.11. add_help 參數

默認情況下,ArgumentParser對象會添加一個選項簡單地顯示解析器的幫助信息。例如,考慮一個包含如下代碼的名為myprogram.py的文件:

import argparse parser = argparse.ArgumentParser() parser.add_argument('--foo', help='foo help') args = parser.parse_args() 

如果在命令行中提供-h或者--help,ArgumentParser的幫助信息將打印出來:

$ python myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO   foo help

偶爾,禁止這個幫助選項也可能是有用的。這可以通過傳遞FalseArgumentParseradd_help=參數實現:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False) >>> parser.add_argument('--foo', help='foo help') >>> parser.print_help() usage: PROG [--foo FOO] optional arguments:  --foo FOO foo help 

該幫助選項通常是-h/--help例外情況是指定了prefix_chars=而且不包括-,在這種情況下-h--help不是合法的選項。在這種情況下,prefix_chars中的第一個字符將用於該幫助選項的前綴:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='+/') >>> parser.print_help() usage: PROG [+h] optional arguments:  +h, ++help show this help message and exit 

 

15.4.3. add_argument() 方法

ArgumentParser. add_argument (name or flags... [, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])

定義應該如何解析一個命令行參數。下面每個參數有它們自己詳細的描述,簡單地講它們是:

  • name or flags - 選項字符串的名字或者列表,例如foo 或者-f, --foo
  • action - 在命令行遇到該參數時采取的基本動作類型。
  • nargs - 應該讀取的命令行參數數目。
  • const - 某些actionnargs選項要求的常數值。
  • default - 如果命令行中沒有出現該參數時的默認值。
  • type - 命令行參數應該被轉換成的類型。
  • choices - 參數可允許的值的一個容器。
  • required - 該命令行選項是否可以省略(只針對可選參數)。
  • help - 參數的簡短描述。
  • metavar - 參數在幫助信息中的名字。
  • dest - parse_args()返回的對象要添加的屬性名稱。

下面的小節描述這些參數如何使用。

15.4.3.1. name 或 flags 參數

add_argument() 方法必須知道期望的是可選參數,比如-f 或者--foo,還是位置參數,比如一個文件列表。傳遞給add_argument() 的第一個參數因此必須是一個標記序列或者一個簡單的參數名字。例如,一個可選的參數可以像這樣創建:

>>>
>>> parser.add_argument('-f', '--foo') 

而一個位置參數可以像這樣創建:

>>>
>>> parser.add_argument('bar') 

當調用parse_args()時,可選的參數將以- 前綴標識,剩余的參數將被假定為位置參數:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-f', '--foo') >>> parser.add_argument('bar') >>> parser.parse_args(['BAR']) Namespace(bar='BAR', foo=None) >>> parser.parse_args(['BAR', '--foo', 'FOO']) Namespace(bar='BAR', foo='FOO') >>> parser.parse_args(['--foo', 'FOO']) usage: PROG [-h] [-f FOO] bar PROG: error: too few arguments 

15.4.3.2. action 參數

ArgumentParser 對象將命令行參數和動作關聯起來。這些動作可以完成與命令行參數關聯的任何事情,盡管大部分動作只是簡單地給parse_args()返回的對象添加一個屬性。action 關鍵字參數指出應該如何處理命令行參數。支持的動作有:

  • 'store' - 只是保存參數的值。這是默認的動作。例如:

    >>>
    >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo') >>> parser.parse_args('--foo 1'.split()) Namespace(foo='1') 
  • 'store_const' - 保存由const關鍵字參數指出的值。(注意const關鍵字參數默認是幾乎沒有幫助的None。)'store_const'動作最常用於指定某種標記的可選參數。例如:

    >>>
    >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='store_const', const=42) >>> parser.parse_args('--foo'.split()) Namespace(foo=42) 
  • 'store_true''store_false' - 它們是'store_const' 的特殊情形,分別用於保存值TrueFalse另外,它們分別會創建默認值False 和True。例如:

    >>>
    >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='store_true') >>> parser.add_argument('--bar', action='store_false') >>> parser.add_argument('--baz', action='store_false') >>> parser.parse_args('--foo --bar'.split()) Namespace(bar=False, baz=True, foo=True) 
  • 'append' - 保存一個列表,並將每個參數值附加在列表的后面。這對於允許指定多次的選項很有幫助。示例用法:

    >>>
    >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='append') >>> parser.parse_args('--foo 1 --foo 2'.split()) Namespace(foo=['1', '2']) 
  • 'append_const' - 保存一個列表,並將const關鍵字參數指出的值附加在列表的后面。(注意const關鍵字參數默認是None。)'append_const' 動作在多個參數需要保存常量到相同的列表時特別有用。例如:

    >>>
    >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--str', dest='types', action='append_const', const=str) >>> parser.add_argument('--int', dest='types', action='append_const', const=int) >>> parser.parse_args('--str --int'.split()) Namespace(types=[<type 'str'>, <type 'int'>]) 
  • 'count' - 計算關鍵字參數出現的次數。例如,這可用於增加詳細的級別:

    >>>
    >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--verbose', '-v', action='count') >>> parser.parse_args('-vvv'.split()) Namespace(verbose=3) 
  • 'help' - 打印當前解析器中所有選項的完整的幫助信息然后退出。默認情況下,help動作會自動添加到解析器中。參見ArgumentParser以得到如何生成輸出信息。

  • 'version' - 它期待version=參數出現在add_argument()調用中,在調用時打印出版本信息並退出:

    >>>
    >>> import argparse >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--version', action='version', version='%(prog)s 2.0') >>> parser.parse_args(['--version']) PROG 2.0 

你還可以通過傳遞一個實現了Action API的對象指定任意一個動作。實現該功能的最簡單方法是擴展argparse.Action,並提供一個合適的__call__方法。__call__方法應該接受四個參數:

  • parser - 包含該動作的ArgumentParser對象。
  • namespace - parse_args()返回的Namespace對象。大部分動作會給該對象添加一個屬性。
  • values - 相關聯的命令行參數於類型轉換之后的值。(類型轉換方式通過add_argument()type關鍵字參數指定。)
  • option_string - 調用該動作的選項字符串。option_string參數是可選的,如果動作關聯的位置參數將不會出現。

自定義動作的例子:

>>>
>>> class FooAction(argparse.Action): ... def __call__(self, parser, namespace, values, option_string=None): ... print '%r %r %r' % (namespace, values, option_string) ... setattr(namespace, self.dest, values) ... >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action=FooAction) >>> parser.add_argument('bar', action=FooAction) >>> args = parser.parse_args('1 --foo 2'.split()) Namespace(bar=None, foo=None) '1' None Namespace(bar='1', foo=None) '2' '--foo' >>> args Namespace(bar='1', foo='2') 

15.4.3.3. nargs 參數

ArgumentParser對象通常將一個動作與一個命令行參數關聯。nargs關鍵字參數將一個動作與不同數目的命令行參數關聯在一起。它支持的值有:

  • N(一個整數)。命令行中的N個參數將被一起收集在一個列表中。例如:

    >>>
    >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs=2) >>> parser.add_argument('bar', nargs=1) >>> parser.parse_args('c --foo a b'.split()) Namespace(bar=['c'], foo=['a', 'b']) 

    注意nargs=1生成一個只有一個元素的列表。這和默認的行為是不一樣的,默認情況下生成的是元素自己。

  • '?'如果有的話就從命令行讀取一個參數並生成一個元素。如果沒有對應的命令行參數,則產生一個來自default的值。注意,對於可選參數,有另外一種情況 - 有選項字符串但是后面沒有跟隨命令行參數。在這種情況下,將生成一個來自const的值。用一些例子加以解釋:

    >>>
    >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs='?', const='c', default='d') >>> parser.add_argument('bar', nargs='?', default='d') >>> parser.parse_args('XX --foo YY'.split()) Namespace(bar='XX', foo='YY') >>> parser.parse_args('XX --foo'.split()) Namespace(bar='XX', foo='c') >>> parser.parse_args(''.split()) Namespace(bar='d', foo='d') 

    nargs='?'的一種更常見的用法是允許可選的輸入和輸出文件:

    >>>
    >>> parser = argparse.ArgumentParser() >>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), ... default=sys.stdin) >>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), ... default=sys.stdout) >>> parser.parse_args(['input.txt', 'output.txt']) Namespace(infile=<open file 'input.txt', mode 'r' at 0x...>,  outfile=<open file 'output.txt', mode 'w' at 0x...>) >>> parser.parse_args([]) Namespace(infile=<open file '<stdin>', mode 'r' at 0x...>,  outfile=<open file '<stdout>', mode 'w' at 0x...>) 
  • '*'出現的所有命令行參數都被收集到一個列表中。注意,一般情況下具有多個帶有nargs='*'的位置參數是不合理的,但是多個帶有nargs='*'的可選參數是可能的。例如:

    >>>
    >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', nargs='*') >>> parser.add_argument('--bar', nargs='*') >>> parser.add_argument('baz', nargs='*') >>> parser.parse_args('a b --foo x y --bar 1 2'.split()) Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y']) 
  • '+''*'一樣,出現的所有命令行參數都被收集到一個列表中。除此之外,如果沒有至少出現一個命令行參數將會產生一個錯誤信息。例如:

    >>>
    >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('foo', nargs='+') >>> parser.parse_args('a b'.split()) Namespace(foo=['a', 'b']) >>> parser.parse_args(''.split()) usage: PROG [-h] foo [foo ...] PROG: error: too few arguments 
  • argparse.REMAINDER.所有剩余的命令行參數都被收集到一個列表中。這通常用於命令行工具分發命令到其它命令行工具:

    >>>
    >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--foo') >>> parser.add_argument('command') >>> parser.add_argument('args', nargs=argparse.REMAINDER) >>> print parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()) Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B') 

如果沒有提供nargs關鍵字參數,讀取的參數個數取決於action通常這意味着將讀取一個命令行參數並產生一個元素(不是一個列表)。

15.4.3.4. const 參數

add_argument()const 參數用於保存常量值,它們不是從命令行讀入但是是ArgumentParser 的動作所要求的。它的兩個最常見的用法是:

  • 當以action='store_const'或者action='append_const'調用add_argument()時。這些動作向parse_args()返回對象的一個屬性添加const值。參見action的描述。
  • 當以選項字符串(例如-f或者--foonargs='?')調用add_argument()時。它創建一個后面可以跟隨零個或者一個命令行字符串的可選參數。當解析命令行參數時,如果選項字符串后面沒有跟隨命令行參數,則假定其為const的值。參見nargs的描述。

const 關鍵字的默認值是None

15.4.3.5. default 參數

所有可選的參數以及某些位置參數可以在命令行中省略。add_argument()default關鍵字參數,其默認值為None,指出如果命令行參數沒有出現時它們應該是什么值。對於可選參數,default的值用於選項字符串沒有出現在命令行中的時候:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', default=42) >>> parser.parse_args('--foo 2'.split()) Namespace(foo='2') >>> parser.parse_args(''.split()) Namespace(foo=42) 

如果default的值是一個字符串,解析器將像命令行參數一樣解析這個值。特別地,在設置Namespace返回值的屬性之前,解析器會調用type的轉換參數。否則,解析器就使用其原始值:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--length', default='10', type=int) >>> parser.add_argument('--width', default=10.5, type=int) >>> parser.parse_args() Namespace(length=10, width=10.5) 

對於nargs等於?或者*的位置參數,default在沒有其命令行參數時使用:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('foo', nargs='?', default=42) >>> parser.parse_args('a'.split()) Namespace(foo='a') >>> parser.parse_args(''.split()) Namespace(foo=42) 

default=argparse.SUPPRESS將導致如果沒有命令行參數時不會添加屬性:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', default=argparse.SUPPRESS) >>> parser.parse_args([]) Namespace() >>> parser.parse_args(['--foo', '1']) Namespace(foo='1') 

15.4.3.6. type 參數

默認情況下,ArgumentParser對象以簡單字符串方式讀入命令行參數。然而,很多時候命令行字符串應該被解釋成另外一種類型,例如浮點數或者整數add_argument()type關鍵字參數允許任意必要的類型檢查並作類型轉換。常見的內建類型和函數可以直接用作type參數的值:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('foo', type=int) >>> parser.add_argument('bar', type=file) >>> parser.parse_args('2 temp.txt'.split()) Namespace(bar=<open file 'temp.txt', mode 'r' at 0x...>, foo=2) 

參見default關鍵字參數一節關於何時type參數應用與默認參數的信息。

為了簡化各種文件類型的使用,argparse提供了工廠類型FileType,它以file對象的mode=bufsize=為參數。例如,FileType('w')可以用於創建一個可寫的文件:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('bar', type=argparse.FileType('w')) >>> parser.parse_args(['out.txt']) Namespace(bar=<open file 'out.txt', mode 'w' at 0x...>) 

type=可以接受任何可調用類型,只要該類型以一個字符串為參數並且返回轉換后的類型:

>>>
>>> def perfect_square(string): ... value = int(string) ... sqrt = math.sqrt(value) ... if sqrt != int(sqrt): ... msg = "%r is not a perfect square" % string ... raise argparse.ArgumentTypeError(msg) ... return value ... >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('foo', type=perfect_square) >>> parser.parse_args('9'.split()) Namespace(foo=9) >>> parser.parse_args('7'.split()) usage: PROG [-h] foo PROG: error: argument foo: '7' is not a perfect square 

choices關鍵字參數對於簡單的某個范圍內的類型檢查可能更方便:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('foo', type=int, choices=xrange(5, 10)) >>> parser.parse_args('7'.split()) Namespace(foo=7) >>> parser.parse_args('11'.split()) usage: PROG [-h] {5,6,7,8,9} PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9) 

更多細節請參閱choices一節。

15.4.3.7. choices 參數

某些命令行參數應該從一個受限的集合中選擇。這種情況的處理可以通過傳遞一個容器對象作為choices關鍵字參數給add_argument()當解析命令行時,將檢查參數的值,如果參數不是一個可接受的值則顯示一個錯誤信息:

>>>
>>> parser = argparse.ArgumentParser(prog='game.py') >>> parser.add_argument('move', choices=['rock', 'paper', 'scissors']) >>> parser.parse_args(['rock']) Namespace(move='rock') >>> parser.parse_args(['fire']) usage: game.py [-h] {rock,paper,scissors} game.py: error: argument move: invalid choice: 'fire' (choose from 'rock', 'paper', 'scissors') 

注意choices 容器包含的對象在type轉換之后檢查,所以choices容器中對象的類型應該與type指出的類型相匹配:

>>>
>>> parser = argparse.ArgumentParser(prog='doors.py') >>> parser.add_argument('door', type=int, choices=range(1, 4)) >>> print(parser.parse_args(['3'])) Namespace(door=3) >>> parser.parse_args(['4']) usage: doors.py [-h] {1,2,3} doors.py: error: argument door: invalid choice: 4 (choose from 1, 2, 3) 

支持in操作符的任何對象都可以傳遞給choices作為它的值,所以dict對象、set對象以及自定義的容器等等都支持。

15.4.3.8. required 參數

一般情況下,argparse模塊假定-f--bar標記表示可選參數,它們在命令行中可以省略。如果要使得選項是必需的,可以指定True作為required=關鍵字參數的值給add_argument()

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', required=True) >>> parser.parse_args(['--foo', 'BAR']) Namespace(foo='BAR') >>> parser.parse_args([]) usage: argparse.py [-h] [--foo FOO] argparse.py: error: option --foo is required 

正如例子所演示的,如果一個命令被標記為required,那么如果命令行中沒有出現該參數parse_args() 將報告一個錯誤。

注意

 

Required 選項一般情況下認為是不好的形式因為用戶期望選項 是可選 的,因此應該盡可能避免這種形式。

15.4.3.9. help 參數

help的值是一個包含參數簡短描述的字符串。當用戶要求幫助時(通常通過使用-h或者--help at the command line),這些help的描述將隨每個參數一起顯示出來:

>>>
>>> parser = argparse.ArgumentParser(prog='frobble') >>> parser.add_argument('--foo', action='store_true', ... help='foo the bars before frobbling') >>> parser.add_argument('bar', nargs='+', ... help='one of the bars to be frobbled') >>> parser.parse_args('-h'.split()) usage: frobble [-h] [--foo] bar [bar ...] positional arguments:  bar one of the bars to be frobbled optional arguments:  -h, --help show this help message and exit  --foo foo the bars before frobbling 

help字符串可以包含各種格式指示符以避免如程序名字和參數default的重復。可用的指示符包括程序的名稱%(prog)s以及大部分add_argument()的關鍵字參數,例如%(default)s%(type)s等:

>>>
>>> parser = argparse.ArgumentParser(prog='frobble') >>> parser.add_argument('bar', nargs='?', type=int, default=42, ... help='the bar to %(prog)s (default: %(default)s)') >>> parser.print_help() usage: frobble [-h] [bar] positional arguments:  bar the bar to frobble (default: 42) optional arguments:  -h, --help show this help message and exit 

通過設置help值為argparse.SUPPRESSargparse支持隱藏特定選項的幫助:

>>>
>>> parser = argparse.ArgumentParser(prog='frobble') >>> parser.add_argument('--foo', help=argparse.SUPPRESS) >>> parser.print_help() usage: frobble [-h] optional arguments:  -h, --help show this help message and exit 

15.4.3.10. metavar 參數

ArgumentParser生成幫助信息時,它需要以某種方式引用每一個參數。 默認情況下,ArgumentParser對象使用dest的值作為每個對象的“名字”。默認情況下,對於位置參數直接使用dest的值,對於可選參數則將dest的值變為大寫。所以,位置參數dest='bar'將引用成bar后面帶有一個命令行參數的可選參數--foo將引用成FOO一個例子:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo') >>> parser.add_argument('bar') >>> parser.parse_args('X --foo Y'.split()) Namespace(bar='X', foo='Y') >>> parser.print_help() usage: [-h] [--foo FOO] bar positional arguments:  bar optional arguments:  -h, --help show this help message and exit  --foo FOO 

可以用metavar指定另外一個名字:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', metavar='YYY') >>> parser.add_argument('bar', metavar='XXX') >>> parser.parse_args('X --foo Y'.split()) Namespace(bar='X', foo='Y') >>> parser.print_help() usage: [-h] [--foo YYY] XXX positional arguments:  XXX optional arguments:  -h, --help show this help message and exit  --foo YYY 

注意metavar只會改變顯示出來的名字 - parse_args() 對象中屬性的名字仍然由dest的值決定。

nargs的不同值可能導致metavar使用多次。傳遞一個列表給metavar將給每個參數指定一個不同的顯示名字:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-x', nargs=2) >>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz')) >>> parser.print_help() usage: PROG [-h] [-x X X] [--foo bar baz] optional arguments:  -h, --help show this help message and exit  -x X X  --foo bar baz 

15.4.3.11. dest 參數

大部分ArgumentParser動作給parse_args()返回對象的某個屬性添加某些值。該屬性的名字由add_argument()dest關鍵字參數決定。對於位置參數的動作,dest 通常作為第一個參數提供給add_argument()

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('bar') >>> parser.parse_args('XXX'.split()) Namespace(bar='XXX') 

對於可選參數的動作,dest的動作通常從選項字符串推導出來。ArgumentParser生成的dest的值是將第一個長的選項字符串前面的--字符串去掉。如果沒有提供長選項字符串,dest的獲得則是將第一個短選項字符串前面的-字符去掉。任何內部的-將被轉換為_字符以確保字符串是合法的屬性名字。下面的實例解釋了這個行為:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('-f', '--foo-bar', '--foo') >>> parser.add_argument('-x', '-y') >>> parser.parse_args('-f 1 -x 2'.split()) Namespace(foo_bar='1', x='2') >>> parser.parse_args('--foo 1 -y 2'.split()) Namespace(foo_bar='1', x='2') 

dest允許提供自定義的屬性名:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', dest='bar') >>> parser.parse_args('--foo XXX'.split()) Namespace(bar='XXX') 

 

15.4.4. parse_args() 方法

ArgumentParser. parse_args (args=None, namespace=None )

將參數字符串轉換成對象並設置成命名空間的屬性。返回構成的命名空間。

之前對add_argument() 的調用完全決定了創建什么對象以及如何設置。詳見add_argument()的文檔。

默認情況下,參數字符串取自於sys.argv,並創建一個空的Namespace對象用於保存屬性。

15.4.4.1. 可選值的語法

parse_args()方法支持幾種指定一個選項的值的方法。最簡單的方法是,將選項和它的值以兩個分開的參數傳遞:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-x') >>> parser.add_argument('--foo') >>> parser.parse_args('-x X'.split()) Namespace(foo=None, x='X') >>> parser.parse_args('--foo FOO'.split()) Namespace(foo='FOO', x=None) 

對於長選項(名字長度超過一個字符的選項),選項和它的值還可以用一個單一的命令行參數傳遞,並用=分隔它們:

>>>
>>> parser.parse_args('--foo=FOO'.split()) Namespace(foo='FOO', x=None) 

對於短選項(長度只有一個字符的選項),選項及其值可以連在一起:

>>>
>>> parser.parse_args('-xX'.split()) Namespace(foo=None, x='X') 

幾個短選項可以連在一起僅使用一個-前綴,只要只有最后一個選項要求有值或者都不要有值:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-x', action='store_true') >>> parser.add_argument('-y', action='store_true') >>> parser.add_argument('-z') >>> parser.parse_args('-xyzZ'.split()) Namespace(x=True, y=True, z='Z') 

15.4.4.2. 非法的參數

在解析命令行的同時,parse_args()會檢查各種錯誤,包括有歧義的選項、不合法的類型、不合法的選項、錯誤的位置參數個數等等。當它遇到此類錯誤時,會退出並跟隨用法信息一起打印出錯誤:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--foo', type=int) >>> parser.add_argument('bar', nargs='?') >>> # invalid type >>> parser.parse_args(['--foo', 'spam']) usage: PROG [-h] [--foo FOO] [bar] PROG: error: argument --foo: invalid int value: 'spam' >>> # invalid option >>> parser.parse_args(['--bar']) usage: PROG [-h] [--foo FOO] [bar] PROG: error: no such option: --bar >>> # wrong number of arguments >>> parser.parse_args(['spam', 'badger']) usage: PROG [-h] [--foo FOO] [bar] PROG: error: extra arguments found: badger 

15.4.4.3. Arguments containing -

parse_args()方法每當用戶犯了明確的錯誤時會努力給出錯誤信息,但是有些情況天生就有歧義。例如,命令行參數-1既可以是想指明一個選項也可以是想提供一個位置參數。這里parse_args()會非常小心:位置參數只有在它們看上去像負數且解析器中沒有選項看上去是負數時才可以以-開始:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-x') >>> parser.add_argument('foo', nargs='?') >>> # no negative number options, so -1 is a positional argument >>> parser.parse_args(['-x', '-1']) Namespace(foo=None, x='-1') >>> # no negative number options, so -1 and -5 are positional arguments >>> parser.parse_args(['-x', '-1', '-5']) Namespace(foo='-5', x='-1') >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-1', dest='one') >>> parser.add_argument('foo', nargs='?') >>> # negative number options present, so -1 is an option >>> parser.parse_args(['-1', 'X']) Namespace(foo=None, one='X') >>> # negative number options present, so -2 is an option >>> parser.parse_args(['-2']) usage: PROG [-h] [-1 ONE] [foo] PROG: error: no such option: -2 >>> # negative number options present, so both -1s are options >>> parser.parse_args(['-1', '-1']) usage: PROG [-h] [-1 ONE] [foo] PROG: error: argument -1: expected one argument 

如果你有必須以- 開始的位置參數且不是負數,你可以插入偽參數'--'告訴parse_args()其后的所有內容都為位置參數:

>>>
>>> parser.parse_args(['--', '-f']) Namespace(foo='-f', one=None) 

15.4.4.4. 參數的縮寫(前綴匹配)

parse_args()方法允許長選項簡寫成一個前綴,如果簡寫的形式沒有歧義(前綴只匹配唯一的一個選項):

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('-bacon') >>> parser.add_argument('-badger') >>> parser.parse_args('-bac MMM'.split()) Namespace(bacon='MMM', badger=None) >>> parser.parse_args('-bad WOOD'.split()) Namespace(bacon=None, badger='WOOD') >>> parser.parse_args('-ba BA'.split()) usage: PROG [-h] [-bacon BACON] [-badger BADGER] PROG: error: ambiguous option: -ba could match -badger, -bacon 

如果參數可能匹配多個選項則生成一個錯誤信息。

15.4.4.5. Beyond sys.argv

有時候可能需要ArgumentParser解析的參數不是來自sys.argv這可以通過傳遞一個字符串列表給parse_args()來完成。這在交互式命令行中測試時很有用:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument( ... 'integers', metavar='int', type=int, choices=xrange(10), ... nargs='+', help='an integer in the range 0..9') >>> parser.add_argument( ... '--sum', dest='accumulate', action='store_const', const=sum, ... default=max, help='sum the integers (default: find the max)') >>> parser.parse_args(['1', '2', '3', '4']) Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4]) >>> parser.parse_args('1 2 3 4 --sum'.split()) Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4]) 

15.4.4.6. Namespace 對象

class argparse.Namespace

parse_args() 默認使用的簡單的類,用於創建一個保存屬性的對象並返回該對象。

這個類故意設計得非常簡單,只是object的一個可以打印可讀字符串的子類。如果你喜歡以字典的形式查看其屬性,可以使用Python標准的語句vars()

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo') >>> args = parser.parse_args(['--foo', 'BAR']) >>> vars(args) {'foo': 'BAR'} 

有時可能需要讓ArgumentParser分配屬性給一個已經存在的對象而不是一個新的Namespace對象。這可以通過指定namespace=關鍵字參數達到:

>>>
>>> class C(object): ... pass ... >>> c = C() >>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo') >>> parser.parse_args(args=['--foo', 'BAR'], namespace=c) >>> c.foo 'BAR' 

 

15.4.5. 其它實用工具

15.4.5.1. 子命令

ArgumentParser. add_subparsers ( [title][, description][, prog][, parser_class][, action][, option_string][, dest][, help][,metavar])

許多程序將它們的功能分成多個子命令,例如,svn可以調用如svn checkoutsvn updatesvn commit子命令。在程序實現的幾個不同的功能要求不同類型的命令行參數時,以這種方式分割程序的功能是特別好的主意。ArgumentParser支持用add_subparsers()方法創建這種子命令。add_subparsers() 方法的調用通常不帶參數並返回一個特殊的動作對象。該對象只有一個方法add_parser(),它的參數是一個命令行名字和任意ArgumentParser構造器,返回的是一個可以像平常一樣修改的ArgumentParser對象。

參數的描述:

  • title - 在輸出的幫助中子解析器組的標題;默認情況下,如果提供description參數則為“subcommands”,否則使用位置參數的標題
  • description - 在輸出的幫助中子解析器組的描述,默認為None
  • prog - 與子命令的幫助一起顯示的使用幫助信息,默認為程序的名字和子解析器參數之前的所有位置參數
  • parser_class - 用於創建子解析器實例的類,默認為當前的解析器(例如ArgumentParser)
  • dest - 子命令的名字應該存儲的屬性名稱;默認為None且不存儲任何值
  • help - 在輸出的幫助中子解析器中的幫助信息,默認為None
  • metavar - 在幫助中表示可用的子命令的字符串;默認為None並以{cmd1, cmd2, ..}的形式表示子命令

一些示例用法:

>>>
>>> # create the top-level parser >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument('--foo', action='store_true', help='foo help') >>> subparsers = parser.add_subparsers(help='sub-command help') >>> >>> # create the parser for the "a" command >>> parser_a = subparsers.add_parser('a', help='a help') >>> parser_a.add_argument('bar', type=int, help='bar help') >>> >>> # create the parser for the "b" command >>> parser_b = subparsers.add_parser('b', help='b help') >>> parser_b.add_argument('--baz', choices='XYZ', help='baz help') >>> >>> # parse some argument lists >>> parser.parse_args(['a', '12']) Namespace(bar=12, foo=False) >>> parser.parse_args(['--foo', 'b', '--baz', 'Z']) Namespace(baz='Z', foo=True) 

注意parse_args()返回的對象只包含主解析器和命令行選擇的子解析器(不包含任何其它子解析器)的屬性。所以在上面的示例中,當指定a命令時,只有foobar屬性,當指定b命令時,只有foobaz 屬性。

類似地,當查看子命令的幫助信息時,只有特定的解析器的幫助會打印出來。幫助信息不包括父解析器和兄弟解析器的信息。(然而,可以通過提供help=參數給add_parser()來給每個子命令添加幫助信息。)

>>>
>>> parser.parse_args(['--help']) usage: PROG [-h] [--foo] {a,b} ... positional arguments:  {a,b} sub-command help  a a help  b b help optional arguments:  -h, --help show this help message and exit  --foo foo help >>> parser.parse_args(['a', '--help']) usage: PROG a [-h] bar positional arguments:  bar bar help optional arguments:  -h, --help show this help message and exit >>> parser.parse_args(['b', '--help']) usage: PROG b [-h] [--baz {X,Y,Z}] optional arguments:  -h, --help show this help message and exit  --baz {X,Y,Z} baz help 

add_subparsers()方法還支持titledescription關鍵字參數。當任意一個出現時,在輸出的幫助中子命令將出現在它們自己的組里。例如:

>>>
>>> parser = argparse.ArgumentParser() >>> subparsers = parser.add_subparsers(title='subcommands', ... description='valid subcommands', ... help='additional help') >>> subparsers.add_parser('foo') >>> subparsers.add_parser('bar') >>> parser.parse_args(['-h']) usage: [-h] {foo,bar} ... optional arguments:  -h, --help show this help message and exit subcommands:  valid subcommands  {foo,bar} additional help 

處理子命令的一個特別有效的方法是將add_subparsers()方法和set_defaults() 調用綁在一起使用,這樣每個子命令就可以知道它應該執行哪個Python 函數。例如:

>>>
>>> # sub-command functions >>> def foo(args): ... print args.x * args.y ... >>> def bar(args): ... print '((%s))' % args.z ... >>> # create the top-level parser >>> parser = argparse.ArgumentParser() >>> subparsers = parser.add_subparsers() >>> >>> # create the parser for the "foo" command >>> parser_foo = subparsers.add_parser('foo') >>> parser_foo.add_argument('-x', type=int, default=1) >>> parser_foo.add_argument('y', type=float) >>> parser_foo.set_defaults(func=foo) >>> >>> # create the parser for the "bar" command >>> parser_bar = subparsers.add_parser('bar') >>> parser_bar.add_argument('z') >>> parser_bar.set_defaults(func=bar) >>> >>> # parse the args and call whatever function was selected >>> args = parser.parse_args('foo 1 -x 2'.split()) >>> args.func(args) 2.0 >>> >>> # parse the args and call whatever function was selected >>> args = parser.parse_args('bar XYZYX'.split()) >>> args.func(args) ((XYZYX)) 

這樣的話,你可以讓parse_args()在參數解析完成之后去做調用適當的函數的工作。像這種方式將函數和動作關聯起來是最簡單的方法來處理你每個子命令的不同動作。然而,如果需要檢查調用的子命令的名字,用dest關鍵字參數調用add_subparsers() 就可以:

>>>
>>> parser = argparse.ArgumentParser() >>> subparsers = parser.add_subparsers(dest='subparser_name') >>> subparser1 = subparsers.add_parser('1') >>> subparser1.add_argument('-x') >>> subparser2 = subparsers.add_parser('2') >>> subparser2.add_argument('y') >>> parser.parse_args(['2', 'frobble']) Namespace(subparser_name='2', y='frobble') 

15.4.5.2. FileType 對象

class argparse.FileType(mode='r', bufsize=None)

FileType創建可以傳遞給ArgumentParser.add_argument()的type參數的對象。FileType對象為類型的參數將用要求的模式和緩沖區大小來打開命令行參數作為文件:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--output', type=argparse.FileType('wb', 0)) >>> parser.parse_args(['--output', 'out']) Namespace(output=<open file 'out', mode 'wb' at 0x...>) 

FileType對象能夠理解偽參數'-' 並主動將它轉換成sys.stdin作為可讀的FileType對象和sys.stdout作為可寫的FileType對象:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('infile', type=argparse.FileType('r')) >>> parser.parse_args(['-']) Namespace(infile=<open file '<stdin>', mode 'r' at 0x...>) 

15.4.5.3. Argument groups

ArgumentParser. add_argument_group (title=None, description=None )

默認情況下,在顯示幫助信息的時候ArgumentParser將命令行參數分成“位置參數”和“可選參數”兩個組。當有比這個默認的分組更好的分組時,可以使用add_argument_group()方法創建合適的分組:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False) >>> group = parser.add_argument_group('group') >>> group.add_argument('--foo', help='foo help') >>> group.add_argument('bar', help='bar help') >>> parser.print_help() usage: PROG [--foo FOO] bar group:  bar bar help  --foo FOO foo help 

add_argument_group()方法返回的參數分組對象具有一個和普通的ArgumentParser一樣的add_argument()方法。當有參數添加進這個分組時解析器會以正常的參數對待,但是在幫助信息中顯示在一個單獨的分組里。add_argument_group()方法接受title和description參數可以用來定制顯示:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False) >>> group1 = parser.add_argument_group('group1', 'group1 description') >>> group1.add_argument('foo', help='foo help') >>> group2 = parser.add_argument_group('group2', 'group2 description') >>> group2.add_argument('--bar', help='bar help') >>> parser.print_help() usage: PROG [--bar BAR] foo group1:  group1 description  foo foo help group2:  group2 description  --bar BAR bar help 

注意任何沒有加入到你自定義的分組中的參數仍將放在通常的“位置參數”和“可選參數”部分。

15.4.5.4. 互斥分組

ArgumentParser. add_mutually_exclusive_group (required=False )

創建一個互斥分組。argparse將確保互斥分組中的一個參數出現在命令行上:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> group = parser.add_mutually_exclusive_group() >>> group.add_argument('--foo', action='store_true') >>> group.add_argument('--bar', action='store_false') >>> parser.parse_args(['--foo']) Namespace(bar=True, foo=True) >>> parser.parse_args(['--bar']) Namespace(bar=False, foo=False) >>> parser.parse_args(['--foo', '--bar']) usage: PROG [-h] [--foo | --bar] PROG: error: argument --bar: not allowed with argument --foo 

add_mutually_exclusive_group()接受一個required 參數,用於指示互斥分組中至少有一個參數是必需的:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG') >>> group = parser.add_mutually_exclusive_group(required=True) >>> group.add_argument('--foo', action='store_true') >>> group.add_argument('--bar', action='store_false') >>> parser.parse_args([]) usage: PROG [-h] (--foo | --bar) PROG: error: one of the arguments --foo --bar is required 

注意目前互斥分組不支持add_argument_group()的title和description 參數。

15.4.5.5. 解析器的默認值

ArgumentParser. set_defaults (**kwargs )

大部分時候,parse_args()返回的對象的屬性完全由命令行參數和參數的動作決定。set_defaults()允許添加一些額外的屬性而不用命令行的解析決定:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('foo', type=int) >>> parser.set_defaults(bar=42, baz='badger') >>> parser.parse_args(['736']) Namespace(bar=42, baz='badger', foo=736) 

注意解析器基本的默認值會永遠覆蓋參數級別的默認值:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', default='bar') >>> parser.set_defaults(foo='spam') >>> parser.parse_args([]) Namespace(foo='spam') 

解析器級別的默認值在使用多個解析器時特別有用。參考add_subparsers()方法可以看到這方面的一個示例。

ArgumentParser. get_default (dest )

獲得namespace某個屬性的默認值,由add_argument()set_defaults()設定:

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', default='badger') >>> parser.get_default('foo') 'badger' 

15.4.5.6. 打印幫助

在大部分典型的應用中,parse_args()將負責用法和錯誤信息的格式和打印。然而,也可以使用幾種格式化的方法:

ArgumentParser. print_usage (file=None )

打印關於如何在命令行上調用ArgumentParser的簡單描述。如果file為None,則假定為sys.stdout

ArgumentParser. print_help (file=None )

打印幫助信息,包括程序的使用方法以及用ArgumentParser注冊的參數信息。如果file為None,則假定為sys.stdout

同樣這些方法還有變體只是簡單地返回字符串而不是打印出來:

ArgumentParser. format_usage ( )

返回一個字符串,包含如何在命令上調用ArgumentParser的簡單描述。

ArgumentParser. format_help ( )

返回一個字符串,包含程序的使用方法以及用ArgumentParser注冊的參數信息。

15.4.5.7. 部分解析

ArgumentParser. parse_known_args (args=None, namespace=None )

有些時候,腳本可能只會解析命令行參數一部分並將剩余的參數傳遞給另外一個腳本或程序。在這些情況下,parse_known_args()方法可以派上用場。除了在出現多余的參數時不會產生錯誤信息以外,它工作的方式與parse_args()非常類似。相反,它返回一個兩個元素的元組,包含構造的namespace和剩余的參數字符串的列表。

>>>
>>> parser = argparse.ArgumentParser() >>> parser.add_argument('--foo', action='store_true') >>> parser.add_argument('bar') >>> parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam']) (Namespace(bar='BAR', foo=True), ['--badger', 'spam']) 

警告

 

Prefix matching規則適用於parse_known_args()解析器將消耗一個選項即使它只是一個已知選項的前綴,而不會將它留在剩余的參數列表中。

15.4.5.8. 定制文件的解析

ArgumentParser. convert_arg_line_to_args (arg_line )

從文件中讀取的參數(參見ArgumentParser構造器的fromfile_prefix_chars關鍵字參數)是按行每行讀取一個參數。可以覆蓋convert_arg_line_to_args()以獲得更好的閱讀體驗。

該方法接受一個參數arg_line,它是從參數文件中讀取出來的一個字符串。它返回從該字符串中解析出來的參數列表。該方法按順序對參數文件中的每一行調用一次。

該方法的一個有用的覆蓋是以空格分隔的單詞作為參數:

def convert_arg_line_to_args(self, arg_line): for arg in arg_line.split(): if not arg.strip(): continue yield arg 

15.4.5.9. 退出的方法

ArgumentParser. exit (status=0, message=None )

該方法將終止程序,以指定的status退出,如果給出message,則會在此之前打印出它。

ArgumentParser. error (message )

該方法打印一個用法信息包括message參數到標准錯誤輸出並以狀態碼2終止程序。

 

15.4.6. 升級optparse的代碼

最初,argparse模塊嘗試保持與optparse的兼容性。然而,optparse很難透明地擴展,特別是新的變化要求支持nargs=指示符和更好的用法幫助信息。optparse中的大部分內容已經被復制粘貼或者胡亂地打上補丁時,試圖維持向后兼容性似乎不太實際。

optparseargparse的部分升級路線:

  • 替換所有的optparse.OptionParser.add_option()調用為ArgumentParser.add_argument()調用。
  • 替換(options, args) parser.parse_args()args parser.parse_args()並為位置參數增加一個額外的ArgumentParser.add_argument()調用。 記住之前叫做options的東西,現在在argparse環境中叫做args
  • 替換回調動作和callback_*關鍵字參數為type或者action參數。
  • 替換type關鍵字參數的字符串名稱為相應的類型對象(例如int、float、complex等)。
  • 替換optparse.ValuesNamespace並替換optparse.OptionErroroptparse.OptionValueError為 ArgumentError
  • 替換隱式參數的字符串為Python 的標准語法以使用字典來格式化字符串,例如替換%default%prog%(default)s%(prog)s
  • 替換OptionParser構造器的version參數為調用parser.add_argument('--version', action='version', version='<the version>')

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM