python實現命令行解析的argparse的使用


參考https://docs.python.org/3.6/library/argparse.html

argparse模塊使編寫用戶友好的命令行界面變得很容易。程序定義了它需要什么參數,argparse將找出如何從sys.argv中解析這些參數。argparse模塊還自動生成幫助和使用消息,並在用戶給程序提供無效參數時發出錯誤。

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的文件中,它可以在命令行運行,如果你沒有輸入任何參數,會報錯:

(deeplearning) userdeMacBook-Pro:pytorch user$ python delete.py 
usage: delete.py [-h] [--sum] N [N ...]
delete.py: error: the following arguments are required: N

使用-h查看有用的幫助信息:

(deeplearning) userdeMacBook-Pro:pytorch user$ 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)

當使用適當的參數運行時,它輸出命令行整數的和或最大值,默認得到的是最大值,添加--sum才指定計算的是和:

(deeplearning) userdeMacBook-Pro:pytorch user$ python prog.py 1 2 3 4
4
(deeplearning) userdeMacBook-Pro:pytorch user$ python prog.py 1 2 3 4 --sum
10

如果傳入無效參數,則會發出錯誤:

(deeplearning) userdeMacBook-Pro:pytorch user$ python prog.py a b c
usage: prog.py [-h] [--sum] N [N ...]
prog.py: error: argument N: invalid int value: 'a'

下面的部分將帶你了解這個示例。

 

1)創建一個parser

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

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

該ArgumentParser對象將保存所有需要的信息去解析命令行到python數據類型中

 

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()將返回一個具有整數和累加兩個屬性的對象。integers屬性將是一個或多個int的列表,而累加屬性將是sum()函數(如果--sum在命令行中指定),或者max()函數(如果沒有制定--sum)。

 

3)解析參數

ArgumentParser通過parse_args()方法解析參數。這將檢查命令行,將每個參數轉換為適當的類型,然后調用適當的操作。在大多數情況下,這意味着一個簡單的命名空間對象將建立從命令行解析的屬性:

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

在腳本中,parse_args()通常沒有參數,ArgumentParser將自動確定sys.argv中的命令行參數。

 parse_args()方法的返回值為namespace,可以用vars()內建函數化為字典

>>> args = parser.parse_args(['--sum', '7', '-1', '42'])
>>>args_dist = vars(args)
{'accumulate' : '[7, -1, 42]'}

 然后調用就可以使用args_dist['accumulate']

 

2.ArgumentParser對象及其參數

class argparse.ArgumentParser:

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, allow_abbrev=True)

創建一個新的ArgumentParser對象。所有參數都應該作為關鍵字參數傳遞。每一個參數都有其更詳細的描述如下,但簡而言之,它們是:

  • prog - 程序的名稱 (default: sys.argv[0])
  • usage - 描述程序使用情況的字符串 (default: 從添加到解析器的參數生成)
  • description - 要在參數幫助信息前顯示的文本 (default: none)
  • epilog - 要在參數幫助信息后顯示的文本 (default: none)
  • parents - ArgumentParser對象的列表,其中也應該包含參數
  • formatter_class - 用於自定義幫助輸出的類
  • prefix_chars - 用於前綴可選參數的字符集 (default: ‘-‘)
  • fromfile_prefix_chars - 前綴文件的一組字符,應從中讀取附加參數 (default: None)
  • argument_default - 參數的全局默認值 (default: None)
  • conflict_handler - 解決選擇沖突的策略 (usually unnecessary)
  • add_help - 添加-h/--help選項到解析器中 (default: True)
  • allow_abbrev - 允許長選項被縮寫,如果縮寫是明確的. (default: True)是3.5版本添加的參數

下面的部分將描述如何使用這些方法。

1)prog

默認情況下,ArgumentParser對象使用sys。以確定如何在幫助消息中顯示程序的名稱。這個缺省值幾乎總是可取的,因為它將使幫助消息與在命令行上調用程序的方式匹配。例如,考慮一個名為myprogram.py的文件,其代碼如下:

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

該程序的幫助將顯示myprogram.py作為程序名,即sys.argv[0]的值(無論程序是從哪里調用的):

(deeplearning) userdeMacBook-Pro:argparse_learning user$ python myprogram.py --help
usage: myprogram.py [-h] [--foo FOO] #可見myprogram.py為程序名

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

(deeplearning) userdeMacBook-Pro:argparse_learning user$ cd ..

(deeplearning) userdeMacBook-Pro:pytorch user$ python argparse_learning/myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

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

要更改此默認行為,可以使用prog= argument向ArgumentParser提供另一個值:

parser = argparse.ArgumentParser(prog = 'myprogram')

這樣再運行可見返回的程序名就變成了myprogram

(deeplearning) userdeMacBook-Pro:pytorch user$ python myprogram.py --help
usage: myprogram [-h] [--foo FOO]

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

另一種查看方法是:

>>> import argparse
>>> parse = argparse.ArgumentParser(prog='myprogram')
>>> parse.print_help()
usage: myprogram [-h]

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

注意,由sys.argv[0]或prog= argument決定的程序名可以使用%(prog)s格式說明符來顯示在幫助消息中:

>>> parse.add_argument('--foo', help='foo of the %(prog)s program') #添加參數是使用
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help='foo of the %(prog)s program', metavar=None)
>>> parse.print_help()
usage: myprogram [-h] [--foo FOO]

optional arguments:
  -h, --help  show this help message and exit
  --foo FOO   foo of the myprogram program
>>> 

 

2)usage

默認情況下,ArgumentParser從它包含的參數中計算使用消息:

>>> parse = argparse.ArgumentParser(prog = 'PROG')
>>> parse.add_argument('--foo', nargs='?', help='foo help')
_StoreAction(option_strings=['--foo'], dest='foo', nargs='?', const=None, default=None, type=None, choices=None, help='foo help', metavar=None)
>>> parse.add_argument('bar', nargs='+', help='bar help')
_StoreAction(option_strings=[], dest='bar', nargs='+', const=None, default=None, type=None, choices=None, help='bar help', metavar=None)
>>> parse.print_help()
usage: PROG [-h] [--foo [FOO]] bar [bar ...] #即這一行的消息可使用usage重寫

positional arguments:
  bar          bar help

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

可以使用usage= keyword參數重寫默認消息:

>>> parse = argparse.ArgumentParser(prog = 'PROG', usage='%(prog)s [option]')
>>> parse.add_argument('--foo', nargs='?', help='foo help')
_StoreAction(option_strings=['--foo'], dest='foo', nargs='?', const=None, default=None, type=None, choices=None, help='foo help', metavar=None)
>>> parse.add_argument('bar', nargs='+', help='bar help')
_StoreAction(option_strings=[], dest='bar', nargs='+', const=None, default=None, type=None, choices=None, help='bar help', metavar=None)
>>> parse.print_help()
usage: PROG [option]

positional arguments:
  bar          bar help

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

 

3)description

對ArgumentParser構造函數的大多數調用將使用description= keyword參數。這個參數簡要描述了程序的功能及其工作原理。在幫助消息中,描述顯示在命令行用法字符串和各種參數的幫助消息之間:

>>> parser = argparse.ArgumentParser(description='a foo that bars')
>>> parser.print_help()
usage: [-h]

a foo that bars #顯示在這里

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

默認情況下,描述description是行包裝形式,以便適合給定的空間。要更改此行為,請參閱formatter_class參數,下面會說明。

 

4)epilog

有些程序喜歡在參數描述之后顯示程序的附加描述。這樣的文本可以使用epilog= argument指定ArgumentParser:

>>> parser = argparse.ArgumentParser(description='a foo that bars',epilog="And that's how you'd foo a bar")
>>> parser.print_help()
usage: [-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= text是行包裝的,但是可以使用formatter_class參數到ArgumentParser調整此行為。

 

5)formatter_class

ArgumentParser對象允許通過指定另一個格式化類來定制幫助格式化。目前有四類:

  • class argparse.RawDescriptionHelpFormatter
  • class argparse.RawTextHelpFormatter
  • class argparse.ArgumentDefaultsHelpFormatter
  • class argparse.MetavarTypeHelpFormatter

RawDescriptionHelpFormatter和RawTextHelpFormatter對文本描述的顯示方式提供了更多的控制。默認情況下,ArgumentParser對象將description和epilog文本行包裝在命令行幫助消息中:

>>> 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已經正確格式化,不應該換行:

補充:textwrap.dedent(text) 
這個方法是用來移除縮進

>>> 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

如果沒有textwrap.dedent(text)。返回:

>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     formatter_class=argparse.RawDescriptionHelpFormatter,
...     description='''\ 
...     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!')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=42, type=<class 'int'>, choices=None, help='FOO!', metavar=None)
>>> parser.add_argument('bar', nargs='*', default=[1, 2, 3], help='BAR!')
_StoreAction(option_strings=[], dest='bar', nargs='*', const=None, default=[1, 2, 3], type=None, choices=None, help='BAR!', metavar=None)
>>> 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) #添加默認值

 

MetavarTypeHelpFormatter為每個參數使用類型參數的名稱作為其值的顯示名稱(而不是像常規格式化程序那樣使用dest指明的顯示名稱):

>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     formatter_class=argparse.MetavarTypeHelpFormatter)
>>> parser.add_argument('--foo', type=int)
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=<class 'int'>, choices=None, help=None, metavar=None)

#比如一般是使用dest='bar'中的bar作為顯示名稱,現在使用的是type=<class 'float'>中的float作為顯示名稱
>>> parser.add_argument('bar', type=float)
_StoreAction(option_strings=[], dest='bar', nargs=None, const=None, default=None, type=<class 'float'>, choices=None, help=None, metavar=None)

>>> parser.print_help()
usage: PROG [-h] [--foo int] float

positional arguments:
  float

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

 

6)parents

有時,幾個解析器共享一組公共參數。與其重復這些參數的定義,不如使用一個包含所有共享參數並傳遞給parent = argument到ArgumentParser的單一解析器。parent = argument獲取一個ArgumentParser對象列表,從其中收集所有的位置操作和可選操作,並將這些操作添加到正在構造的ArgumentParser對象中:

>>> parent_parser = argparse.ArgumentParser(add_help=False) #定義父解析器
>>> parent_parser.add_argument('--parent',type=int)
_StoreAction(option_strings=['--parent'], dest='parent', nargs=None, const=None, default=None, type=<class 'int'>, choices=None, help=None, metavar=None)

>>> foo_parser  = argparse.ArgumentParser(parents=[parent_parser])
>>> foo_parser.add_argument('foo')
_StoreAction(option_strings=[], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
#測試傳入的參數為'--parent', '2', 'XXX'時,得到的對應各個參數的值
>>> foo_parser.parse_args(['--parent', '2', 'XXX'])
Namespace(foo='XXX', parent=2)

>>> bar_parser = argparse.ArgumentParser(parents=[parent_parser])
>>> bar_parser.add_argument('--bar')
_StoreAction(option_strings=['--bar'], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> bar_parser.parse_args(['--bar', 'YYY'])
Namespace(bar='YYY', parent=None)

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

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

 看上面的例子可以看出,如果前面有寫--bar類的標簽,則其后面的參數就是這個標簽對應的值,然后其后面的值就是其他的參數的值

 

7)prefix_chars

大多數命令行選項將使用-作為前綴,例如-f/--foo。需要支持不同或額外前綴字符的解析器,例如+f或/foo選項,可以使用ArgumentParser構造函數的prefix_chars= argument指定它們:

>>> parser = argparse.ArgumentParser(prog='PROG', prefix_chars='-+')
>>> parser.add_argument('+f')
_StoreAction(option_strings=['+f'], dest='f', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('++bar')
_StoreAction(option_strings=['++bar'], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('+f X ++bar Y'.split())
Namespace(bar='Y', f='X')

prefix_chars=參數默認為'-'。提供一組不包含-的字符將導致-f/--foo選項被禁用。

 

8)fromfile_prefix_chars

有時,例如,當處理一個特別長的參數列表時,將參數列表保存在一個文件中,而不是在命令行中鍵入參數,可能是有意義的。如果將fromfile_prefix_chars=argument提供給ArgumentParser構造函數,那么以任何指定字符argument開頭的參數都將被視為文件,並由它們包含的參數替換。例如:

>>> with open('args.txt', 'w') as fp:
...     fp.write('-f\nbar')
... 
6  #返回文件內容的大小
>>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
>>> parser.add_argument('-f')
_StoreAction(option_strings=['-f'], dest='f', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['-f', 'foo', '@args.txt'])
Namespace(f='bar')
>>> parser.parse_args(['-f', 'foo']) #如果沒有使用上面的'@args.txt'返回的結果是
Namespace(f='foo')

默認情況下,從文件中讀取的參數必須是每行一個(但也請參閱convert_arg_line_to_args()),並將其視為與在命令行中引用參數的原始文件位於同一位置。在上面的例子中,表達式['-f', 'foo', '@args。txt']被認為等同於表達式['-f', 'foo', '-f', 'bar']。

fromfile_prefix_chars=參數默認為None,這意味着參數永遠不會被視為文件引用。

 

9)argument_default

通常,通過將默認值傳遞給add_argument()或使用一組特定的名稱-值對調用set_defaults()方法來指定參數默認值。然而,有時為參數指定一個解析器范圍的默認值可能很有用。這可以通過將argument_default=keyword 參數傳遞給ArgumentParser來實現。例如,為了全局地抑制parse_args()調用上的屬性創建,我們提供argument_default= SUPPRESS:

>>> argparse.SUPPRESS
'==SUPPRESS=='
>>> parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
>>> parser.add_argument('--foo')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default='==SUPPRESS==', type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('bar', nargs='?')
_StoreAction(option_strings=[], dest='bar', nargs='?', const=None, default='==SUPPRESS==', type=None, choices=None, help=None, metavar=None)

>>> parser.parse_args(['--foo', '1', 'BAR'])
Namespace(bar='BAR', foo='1')
>>> parser.parse_args([])
Namespace()

 提供default=argparse.SUPPRESS,如果命令行參數不存在,則不會添加任何屬性,無默認值

 

10)allow_abbrev

通常,當你將參數列表傳遞給ArgumentParser的parse_args()方法時,它會識別長選項的縮寫。

這個功能可以通過設置allow_abbrev為False來禁用:

>>> parser = argparse.ArgumentParser(prog='PROG', allow_abbrev=False)
>>> parser.add_argument('--foobar', action='store_true')
_StoreTrueAction(option_strings=['--foobar'], dest='foobar', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('--foonley', action='store_false')
_StoreFalseAction(option_strings=['--foonley'], dest='foonley', nargs=0, const=False, default=True, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['--foon'])
usage: PROG [-h] [--foobar] [--foonley]
PROG: error: unrecognized arguments: --foon

如果沒有設置可見可以使用--foon縮寫:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foobar', action='store_true')
_StoreTrueAction(option_strings=['--foobar'], dest='foobar', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('--foonley', action='store_false')
_StoreFalseAction(option_strings=['--foonley'], dest='foonley', nargs=0, const=False, default=True, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['--foon']) #因為這里沒有設置--foobar所以返回false,如果設置應該為true
Namespace(foobar=False, foonley=False)

New in version 3.5.

 

11)conflict_handler

ArgumentParser對象不允許兩個具有相同選項字符串的操作。默認情況下,如果使用已經使用的選項字符串創建參數,ArgumentParser對象會引發異常:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo', help='old foo help')
_StoreAction(option_strings=['-f', '--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help='old foo help', metavar=None)
>>> parser.add_argument('--foo', help='new foo help')
Traceback (most recent call last):
...  
File "/anaconda3/envs/deeplearning/lib/python3.6/argparse.py", line 1514, in _handle_conflict_error
    raise ArgumentError(action, message % conflict_string)
argparse.ArgumentError: argument --foo: conflicting option string: --foo

有時(例如,當使用父類時),簡單地用相同的選項字符串覆蓋任何舊的參數可能是有用的。要獲得這種行為,可以將值'resolve'提供給ArgumentParser的conflict_handler= argument

即如果你想要覆蓋操作實現而不是報錯:

>>> parser = argparse.ArgumentParser(prog='PROG', conflict_handler='resolve')
>>> parser.add_argument('-f', '--foo', help='old foo help')
_StoreAction(option_strings=['-f', '--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help='old foo help', metavar=None)
>>> parser.add_argument('--foo', help='new foo help')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help='new foo help', metavar=None)
>>> 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選項字符串。

即你調用-f是執行的是old foo help, --foo時執行的是new foo help

 

12)add_help

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

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

如果在命令行中提供-h或--help,將打印ArgumentParser help:

(deeplearning) userdeMacBook-Pro:argparse_learning user$ python myprogram.py --help
usage: myprogram.py [-h] [--foo FOO]

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

有時,禁用此幫助選項的添加可能很有用。這可以通過將False作為add_help=argument傳遞給ArgumentParser來實現:

>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
>>> parser.add_argument('--foo', help='foo help')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help='foo help', metavar=None)
>>> parser.print_help()
usage: PROG [--foo FOO]

optional arguments:
  --foo FOO  foo help

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

 

3.add_argument()方法及其參數

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

定義如何解析單個命令行參數。每個參數在下面都有自己更詳細的描述:

  • name or flags - 名稱或選項字符串列表, e.g. foo or -f, --foo.
  • action - 在命令行中遇到此參數時要采取的基本操作類型.
  • nargs - 應該使用的命令行參數的數量.
  • const - 某些操作和nargs選擇所需的常量.
  • default - 如果參數不在命令行中,則生成的默認值.
  • type - 應將命令行參數轉換為的類型.
  • choices - 參數的允許值的容器.
  • required - 是否可以省略命令行選項 (只可選).
  • help - 簡單描述一下這個參數的作用.
  • metavar - usage消息中參數的名稱.
  • dest - 要添加到parse_args()返回的對象中的屬性的名稱

下面的部分將描述如何使用這些方法。

1)name or flags

add_argument()方法必須知道是否需要一個可選參數,比如-f或--foo,或者一個位置參數,比如文件名列表。因此,傳遞給add_argument()的第一個參數必須是一系列標志,或者是一個簡單的參數名。例如,可以創建一個可選參數,如下所示:

一系列標志:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-f', '--foo')
_StoreAction(option_strings=['-f', '--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

或一個簡單的參數名:

>>> parser.add_argument('bar')
_StoreAction(option_strings=[], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

 

2)action

ArgumentParser對象將命令行參數與操作關聯起來。這些操作可以對與之關聯的命令行參數執行任何操作,盡管大多數操作只是向parse_args()返回的對象添加一個屬性。action關鍵字參數指定應該如何處理命令行參數。所提供的操作如下:

  • 'store' - 它只存儲參數的值。這是默認操作,即不用特殊指定。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo') #默認action='store'
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('--foo 1'.split())
Namespace(foo='1')
  • 'store_const' - 它存儲由const關鍵字參數指定的值。“store_const”操作通常與指定某種標志的可選參數一起使用,如const=。將參數設置為某常量值。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
_StoreConstAction(option_strings=['--foo'], dest='foo', nargs=0, const=42, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['--foo'])
Namespace(foo=42)

⚠️不能寫成:

>>> parser.parse_args('--foo')
usage: [-h] [--foo]
: error: unrecognized arguments: - - f o o
  • 'store_true' and 'store_false' - 這些是'store_const'的特殊情況,分別用於存儲值True和False。此外,它們分別創建False和True的默認值。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_true')
_StoreTrueAction(option_strings=['--foo'], dest='foo', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('--bar', action='store_false')
_StoreFalseAction(option_strings=['--bar'], dest='bar', nargs=0, const=False, default=True, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('--baz', action='store_false')
_StoreFalseAction(option_strings=['--baz'], dest='baz', nargs=0, const=False, default=True, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('--foo --bar --baz'.split())
Namespace(bar=False, baz=False, foo=True)

如果你沒有設置解析--foo,其返回值會是false:

>>> parser.parse_args('--bar --baz'.split())
Namespace(bar=False, baz=False, foo=False)
  • 'append' -它存儲一個列表,並將每個參數值附加到列表中。這對於允許多次指定某個選項非常有用。使用示例:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
_AppendAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])
  • 'append_const' - 它存儲一個列表,並將const關鍵字參數指定的值附加到列表中。(注意const關鍵字參數默認為None。)當多個參數需要將常量存儲到同一個列表中時,“append_const”操作通常非常有用。例如:
>>> parser = argparse.ArgumentParser()
#dest='types'使得使用parse_args()時該值的返回參數名為Namespace(types=...)
>>> parser.add_argument('--str', dest='types', action='append_const', const=str) 
_AppendConstAction(option_strings=['--str'], dest='types', nargs=0, const=<class 'str'>, default=None, type=None, choices=None, help=None, metavar=None)

>>> parser.add_argument('--int', dest='types', action='append_const', const=int) 
_AppendConstAction(option_strings=['--int'], dest='types', nargs=0, const=<class 'int'>, default=None, type=None, choices=None, help=None, metavar=None)

#從返回可見這兩個const值會被一起存儲在一個列表中
>>> parser.parse_args('--str --int'.split())
Namespace(types=[<class 'str'>, <class 'int'>])
>>> parser.print_help()
usage: [-h] [--str] [--int]

optional arguments:
  -h, --help  show this help message and exit
  --str
  --int
  • 'count' - 這將計算關鍵字參數出現的次數。例如,這對於增加冗長程度很有用:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--verbose', '-v', action='count')
_CountAction(option_strings=['--verbose', '-v'], dest='verbose', nargs=0, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['-vvv'])
Namespace(verbose=3)
  • 'help' - 這將為當前解析器中的所有選項打印完整的幫助消息,然后退出。默認情況下,幫助操作會自動添加到解析器中。有關如何創建輸出的詳細信息,請參見ArgumentParser。

  • 'version' - 這需要在add_argument()調用中使用version= keyword參數,並在調用時打印version信息並退出:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--version', action='version', version='%(prog)s 2.0')
_VersionAction(option_strings=['--version'], dest='version', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help="show program's version number and exit", metavar=None)
>>> parser.parse_args(['--version'])
PROG 2.0
(deeplearning) userdeMacBook-Pro:pytorch-learning user$ 

 

還可以通過傳遞實現相同接口的action子類或其他對象來指定任意操作。推薦的方法是擴展Action,覆蓋__call__方法和可選的__init__方法。

自定義action操作的一個例子:

>>> import argparse
>>> class FooAction(argparse.Action):
...     def __init__(self, option_strings, dest, nargs=None, **kwargs):
...             if nargs is not None:
...                     raise ValueError("nargs not allowed")
...             super(FooAction, self).__init__(option_strings, dest, **kwargs)
...     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)
FooAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('bar', action=FooAction)
FooAction(option_strings=[], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

>>> args = parser.parse_args('1 --foo 2'.split()) #等價於輸入['1', '--foo', '2']
Namespace(bar=None, foo=None) '1' None #可見這里是先將1賦值給bar
Namespace(bar='1', foo=None) '2' '--foo' #然后將輸入'--foo'作為option_string,並將2賦值給foo
>>> args
Namespace(bar='1', foo='2')

For more details, see Action.即下面的Action classes

 

Action classes

Action類實現Action API,一個可調用的API返回一個可調用的API,該API處理命令行中的參數。任何遵循此API的對象都可以作為action參數傳遞給add_argument()。

class argparse.Action

class argparse.Action(option_strings, dest, nargs=None, const=None, default=None, type=None, choices=None, required=False, help=None, metavar=None)

ArgumentParser使用Action對象來表示從命令行中的一個或多個字符串解析單個參數所需的信息。Action類必須接受兩個位置參數以及傳遞給ArgumentParser.add_argument()的關鍵字參數(除了Action本身)。

Action實例(或任何可調用Action參數的返回值)應該定義屬性“dest”、“option_string”、“default”、“type”、“required”、“help”等。確保定義這些屬性的最簡單方法是調用Action.__init__。

Action實例應該是可調用的,因此子類必須覆蓋__call__方法,該方法應該接受四個參數:

  • parser - 包含此操作的ArgumentParser對象.
  • namespace - 將由parse_args()返回的名稱空間對象。大多數操作使用setattr()向該對象添加屬性.
  • values - 關聯的命令行參數,以及應用的任何類型轉換。類型轉換由type關鍵字參數指定給add_argument().
  • option_string -  用於調用此操作的選項字符串,即帶--的。option_string參數是可選的,如果操作與位置參數關聯,則該參數將不存在.

__call__方法可以執行任意操作,但通常會基於dest和值在名稱空間上設置屬性。

 

 

3)nargs

ArgumentParser對象通常將一個命令行參數與一個要執行的操作關聯起來。nargs關鍵字參數將不同數量的命令行參數與一個操作關聯起來。支持的值是:

  • N(整數):命令行中的N個參數將被收集到一個列表中。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs=2) #指明其需要兩個參數
_StoreAction(option_strings=['--foo'], dest='foo', nargs=2, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('bar', nargs=1) #指明需要一個參數
_StoreAction(option_strings=[], dest='bar', nargs=1, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('c --foo a b'.split())
Namespace(bar=['c'], foo=['a', 'b'])

注意,nargs=1生成一個包含一項的列表。這與默認值不同,默認值中項目是由自己生成的。

  • ' ? ':如果可能,一個參數將從命令行中使用,並作為單個項目生成。如果不存在命令行參數,則會生成默認值。注意,對於可選參數,還有另外一種情況——出現了選項字符串,但后面沒有命令行參數。即可以接受0個或1個參數。在本例中,將生成來自const的值,在解析命令行時,如果遇到選項字符串后面沒有命令行參數,即0個參數,那么將使用const的值。一些例子可以說明這一點:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='?', const='c', default='d')
_StoreAction(option_strings=['--foo'], dest='foo', nargs='?', const='c', default='d', type=None, choices=None, help=None, metavar=None)

>>> parser.add_argument('bar', nargs='?', default='d')
_StoreAction(option_strings=[], dest='bar', nargs='?', const=None, default='d', type=None, choices=None, help=None, metavar=None)

>>> parser.parse_args(['XX', '--foo', 'YY'])
Namespace(bar='XX', foo='YY')
>>> parser.parse_args(['XX', '--foo'])
Namespace(bar='XX', foo='c')
>>> parser.parse_args([]) #如果不指定,將使用默認值
Namespace(bar='d', foo='d')

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

>>> import argparse, sys
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)
_StoreAction(option_strings=[], dest='infile', nargs='?', const=None, default=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>, type=FileType('r'), choices=None, help=None, metavar=None)
>>> parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'), default=sys.stdout)
_StoreAction(option_strings=[], dest='outfile', nargs='?', const=None, default=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>, type=FileType('w'), choices=None, help=None, metavar=None)

#此時當前目錄下必須有文件input.txt,運行完后會在當前目錄生成output.txt文件
>>> parser.parse_args(['input.txt', 'output.txt'])
Namespace(infile=<_io.TextIOWrapper name='input.txt' mode='r' encoding='UTF-8'>, outfile=<_io.TextIOWrapper name='output.txt' mode='w' encoding='UTF-8'>)

>>> parser.parse_args([])
Namespace(infile=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>, outfile=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>)
  • '*' : 所有當前的命令行參數都被收集到一個列表中。注意,使用多個nargs='*'的位置參數通常沒有多大意義,但是使用nargs='*'的多個可選參數是可能的,即可以使用0個或多個參數。例如:
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='*')
_StoreAction(option_strings=['--foo'], dest='foo', nargs='*', const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('--bar', nargs='*')
_StoreAction(option_strings=['--bar'], dest='bar', nargs='*', const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('baz', nargs='*')
_StoreAction(option_strings=[], dest='baz', nargs='*', const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('a b --foo x y --bar 1 2'.split())
Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
>>> parser.parse_args('a b --foo x --bar'.split())
Namespace(bar=[], baz=['a', 'b'], foo=['x'])
  • '+' : 就像'*'一樣,所有的命令行arg都被收集到一個列表中。不同在於,如果沒有至少一個命令行參數,將生成錯誤消息,即接受1個或多個參數。例如:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', nargs='+')
_StoreAction(option_strings=[], dest='foo', nargs='+', const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['a', 'b'])
Namespace(foo=['a', 'b'])
>>> parser.parse_args([]) #如果沒有參數將會報錯
usage: PROG [-h] foo [foo ...]
PROG: error: the following arguments are required: foo
  • argparse.REMAINDER : 所有剩余的命令行參數都被收集到一個列表中。這對於調度到其他命令行實用程序的命令行實用程序通常很有用:
>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

>>> parser.add_argument('command')
_StoreAction(option_strings=[], dest='command', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

>>> parser.add_argument('args', nargs=argparse.REMAINDER) #會將其他參數以外的其他參數當作自己的參數
_StoreAction(option_strings=[], dest='args', nargs='...', const=None, default=None, type=None, choices=None, help=None, metavar=None)

>>> parser.parse_args('--foo B cmd --arg1 XX zz'.split())
Namespace(args=['--arg1', 'XX', 'zz'], command='cmd', foo='B')

如果沒有提供nargs關鍵字參數,則使用的參數數量由action決定。通常,這意味着將使用一個命令行參數,並生成一個項目(而不是列表)。

 

4)const

 add_argument()的const參數用於保存常量,這些常量不是從命令行讀取的,而是用於各種ArgumentParser操作。它最常見的兩個用途是:

  • 當使用action='store_const'或action='append_const'調用add_argument()時。這些操作將const值添加到parse_args()返回的對象的一個屬性中。上面介紹action時有使用到
  • 當使用選項字符串(如-f或--foo)和nargs='?'調用add_argument()時。這將創建一個可選參數,后面可以跟着零個或一個命令行參數。在解析命令行時,如果遇到選項字符串后面沒有命令行參數,那么將使用const的值。有關示例,請參見nargs描述。

對於“store_const”和“append_const”操作,必須給出const關鍵字參數。對於其他操作,默認為None。

 

5)default

所有可選參數和一些位置參數都可以在命令行中省略。add_argument()的default關鍵字參數的值默認為None,它指定如果命令行參數不存在,應該使用什么值。對於可選參數,在命令行不存在選項字符串時使用默認值:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=42, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['--foo', '2'])
Namespace(foo='2')
>>> parser.parse_args([])
Namespace(foo=42)

如果默認值是字符串,則解析器將解析該值,就像解析命令行參數一樣。特別是,在設置Namespace返回值的屬性之前,如果提供了類型轉換參數,解析器將應用任何類型轉換參數。否則,解析器將使用如下值:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--length', default='10', type=int)
_StoreAction(option_strings=['--length'], dest='length', nargs=None, const=None, default='10', type=<class 'int'>, choices=None, help=None, metavar=None)
>>> parser.add_argument('--width', default=10.5, type=int)
_StoreAction(option_strings=['--width'], dest='width', nargs=None, const=None, default=10.5, type=<class 'int'>, choices=None, help=None, metavar=None)
>>> parser.parse_args()
Namespace(length=10, width=10.5)

對於帶有nargs等於?或*的位置參數,當沒有命令行參數時使用default默認值:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', nargs='?', default=42)
_StoreAction(option_strings=[], dest='foo', nargs='?', const=None, default=42, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['a'])
Namespace(foo='a')
>>> parser.parse_args([])
Namespace(foo=42)

提供default=argparse.SUPPRESS,如果命令行參數不存在,則不會添加任何屬性,無默認值:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=argparse.SUPPRESS)
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default='==SUPPRESS==', type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args([])
Namespace()
>>> parser.parse_args(['--foo', '1'])
Namespace(foo='1')

 

6)type

默認情況下,ArgumentParser對象以簡單字符串的形式讀取命令行參數。然而,命令行字符串通常應該被解釋為另一種類型,比如float或int。add_argument()的type關鍵字參數允許執行任何必要的類型檢查和類型轉換。常見的內置類型和函數可以直接用作type參數的值:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
_StoreAction(option_strings=[], dest='foo', nargs=None, const=None, default=None, type=<class 'int'>, choices=None, help=None, metavar=None)
>>> parser.add_argument('bar', type=open)
_StoreAction(option_strings=[], dest='bar', nargs=None, const=None, default=None, type=<built-in function open>, choices=None, help=None, metavar=None)
>>> parser.parse_args('2 input.txt'.split())
Namespace(bar=<_io.TextIOWrapper name='input.txt' mode='r' encoding='UTF-8'>, foo=2)

有關類型參數何時應用於默認參數的信息,請參閱上面default關鍵字參數一節。

為了方便使用各種類型的文件,argparse模塊提供了工廠FileType,它接受open()函數的mode=、bufsize=、encoding=和errors=arguments。例如,FileType('w')可以用來創建一個可寫文件:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar', type=argparse.FileType('w'))
_StoreAction(option_strings=[], dest='bar', nargs=None, const=None, default=None, type=FileType('w'), choices=None, help=None, metavar=None)
>>> parser.parse_args(['output.txt'])
Namespace(bar=<_io.TextIOWrapper name='output.txt' mode='w' encoding='UTF-8'>)

type=可以接受任何接受單個字符串參數並返回轉換值的可調用值:

>>> def perfect_square(string): #判斷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)
_StoreAction(option_strings=[], dest='foo', nargs=None, const=None, default=None, type=<function perfect_square at 0x1018b47b8>, choices=None, help=None, metavar=None)
>>> parser.parse_args(['9']) #該傳入的值將作為perfect_square的參數值string,返回值將作為foo的值
Namespace(foo=9)
>>> parser.parse_args(['7'])
usage: PROG [-h] foo
PROG: error: argument foo: '7' is not a perfect square

See the choices section for more details.即下面

 

7)choices

應該從一組受限制的值中選擇一些命令行參數。可以通過將容器對象作為choice關鍵字參數傳遞給add_argument()來處理這些問題。當解析命令行時,將檢查參數值,如果參數不是可接受的值之一,將顯示錯誤消息:

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='game.py')
>>> parser.add_argument('move', choices=['rock', 'paper', 'scissors'])
_StoreAction(option_strings=[], dest='move', nargs=None, const=None, default=None, type=None, choices=['rock', 'paper', 'scissors'], help=None, metavar=None)
>>> parser.parse_args(['rock'])
Namespace(move='rock')
>>> parser.parse_args(['fire']) #不是choices里面的值,將會返回錯誤
usage: game.py [-h] {rock,paper,scissors}
game.py: error: argument move: invalid choice: 'fire' (choose from 'rock', 'paper', 'scissors')

注意,在執行任何類型轉換之后,都會檢查choices容器中的內容,因此choices容器中的對象的類型應該與指定的type類型匹配:

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='doors.py')
>>> parser.add_argument('door', type=int, choices=range(1,4))
_StoreAction(option_strings=[], dest='door', nargs=None, const=None, default=None, type=<class 'int'>, choices=range(1, 4), help=None, metavar=None)
>>> 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對象、定制容器等都是受支持的。

 

8)required

通常,argparse模塊假設-f和--bar等標志表示可選參數,這些參數在命令行中總是可以省略。要使選項成為必需的,可以為required= keyword參數指定True,然后將其指定為add_argument():

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', required=True)
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['--foo', 'BAR'])
Namespace(foo='BAR')
>>> parser.parse_args([]) #必須要有--foo,不然報錯
usage: [-h] --foo FOO
: error: the following arguments are required: --foo

如示例所示,如果一個選項被標記為required,那么如果該選項不在命令行中,parse_args()將報告一個錯誤。

⚠️必需選項通常被認為是不好的形式,因為用戶希望選項是可選的,因此應該盡可能避免使用它們

 

9)help

help值是一個字符串,包含參數的簡短描述。當用戶請求幫助(通常在命令行使用-h或--help)時,這些幫助描述將與每個參數一起顯示:

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', action='store_true', help='foo the bars before frobbling')
_StoreTrueAction(option_strings=['--foo'], dest='foo', nargs=0, const=True, default=False, type=None, choices=None, help='foo the bars before frobbling', metavar=None)
>>> parser.add_argument('bar', nargs='+' , help='one of the bars to be frobbled')
_StoreAction(option_strings=[], dest='bar', nargs='+', const=None, default=None, type=None, choices=None, help='one of the bars to be frobbled', metavar=None)
>>> parser.parse_args(['-h'])
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字符串可以包含各種格式說明符,以避免重復程序名或參數默認值等內容。可用的說明符包括程序名、%(prog)s和add_argument()的大多數關鍵字參數,例如%(default)s獲取默認值、%(type)s獲取類型值等:

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('bar', nargs='?', type=int, default=42, help='the bar to %(prog)s (default: %(default)s)')
_StoreAction(option_strings=[], dest='bar', nargs='?', const=None, default=42, type=<class 'int'>, choices=None, help='the bar to %(prog)s (default: %(default)s)', metavar=None)
>>> 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字符串支持%-格式化,如果希望幫助字符串中出現文字%,則必須將其轉義為%%。

通過將help值設置為argparse.SUPPRESS, argparse支持對某些選項禁用help條目:

>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo', help=argparse.SUPPRESS)
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help='==SUPPRESS==', metavar=None)
>>> parser.print_help()
usage: frobble [-h]

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

沒有禁用的輸出是:

>>> parser = argparse.ArgumentParser(prog='frobble')
>>> parser.add_argument('--foo')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.print_help()
usage: frobble [-h] [--foo FOO]

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

 

10)metavar:定義期望參數的名字

當ArgumentParser生成help消息時,它需要某種方法來引用每個期望的參數。默認情況下,ArgumentParser對象使用dest值作為每個對象的“名稱”。默認情況下,對於位置參數操作,dest值直接使用,對於可選參數操作,dest值大寫。因此,一個位置參數dest='bar'將被稱為bar。一個可選參數--foo,后面應該跟着一個命令行參數,該命令行參數將被稱為FOO。

一個例子:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('bar')
_StoreAction(option_strings=[], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> 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')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar='YYY')
>>> parser.add_argument('bar', metavar='XXX')
_StoreAction(option_strings=[], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, 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) #不使用metavar,則help參數名默認為其大寫
_StoreAction(option_strings=['-x'], dest='x', nargs=2, const=None, default=None, type=None, choices=None, help=None, metavar=None)

>>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
_StoreAction(option_strings=['--foo'], dest='foo', nargs=2, const=None, default=None, type=None, choices=None, help=None, 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

 

11)dest:決定parse_args()對象上的屬性名稱

大多數ArgumentParser動作都會添加一些值作為parse_args()返回的對象的屬性。此屬性的名稱由add_argument()的dest關鍵字參數決定。

對於位置參數操作,dest通常作為add_argument()的第一個參數提供:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar') #位置參數
_StoreAction(option_strings=[], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['XXX'])
Namespace(bar='XXX')

對於可選參數操作,dest的值通常從選項字符串推斷。

推斷順序:

  • ArgumentParser通過獲取第一個長選項字符串並去掉初始 -- 字符串來生成dest的值,如下面的--foo的dest值為foo
  • 如果沒有提供長選項字符串,dest將從第一個短選項字符串中去掉初始的-字符來提取值,如下面的-x的dest值為x。

任何內部-字符將被轉換為_字符,以確保字符串是一個有效的屬性名,如下面的--foo-bar的dest名為foo_bar

下面的例子說明了這種行為:

>>> parser = argparse.ArgumentParser()
#你調用'-f', '--foo-bar', '--foo'任何之一的效果都是一樣的,只是在parse_args()中顯示的名字都是dest的值
>>> parser.add_argument('-f', '--foo-bar', '--foo')
_StoreAction(option_strings=['-f', '--foo-bar', '--foo'], dest='foo_bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
#你調用'-x', '-y'任何之一的效果都是一樣的,只是在parse_args()中顯示的名字都是dest的值
>>> parser.add_argument('-x', '-y')
_StoreAction(option_strings=['-x', '-y'], dest='x', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> 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')
>>> parser.print_help()
usage: [-h] [-f FOO_BAR] [-x X]

optional arguments:
  -h, --help            show this help message and exit
  -f FOO_BAR, --foo-bar FOO_BAR, --foo FOO_BAR
  -x X, -y X

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

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', dest='bar') #自定義名為'bar'
_StoreAction(option_strings=['--foo'], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('--foo XXX'.split())
Namespace(bar='XXX')

 

4.parse_args()方法

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

將參數字符串轉換為對象,並將它們指定為名稱空間的屬性。返回填充的名稱空間。

之前對add_argument()的調用確定了創建什么對象以及如何分配對象。有關詳細信息,請參閱上面add_argument()的介紹。

  • args - 要解析的字符串列表。默認值取自sys.argv.
  • namespace - 獲取屬性的對象。默認值是一個新的空名稱空間對象.

舉例:

>>> class C: #聲明一個對象用作namespace對象
...     pass
... 
>>> c = C()
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(args=['--foo', 'BAR'], namespace=c) #這樣這里就不會使用新的namespace對象了
<__main__.C object at 0x10baf6a20>
>>> c.foo
'BAR'

 

1)可選值語法

parse_args()方法支持幾種指定選項值的方法(如果接受一種方法)。

1> 在最簡單的情況下,該選項及其值作為兩個單獨的參數傳遞:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
_StoreAction(option_strings=['-x'], dest='x', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('--foo')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['-x', 'X'])
Namespace(foo=None, x='X')
>>> parser.parse_args(['--foo', 'FOO'])
Namespace(foo='FOO', x=None)

 

2>對於長選項(名稱大於單個字符的選項),也可以將選項和值作為單個命令行參數傳遞,使用=分隔它們:

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

 

3>對於較短的選項(選項只有一個字符長),可以將該選項及其值連接起來:

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

 

4>幾個短選項可以連接在一起,只使用一個前綴,只要只有最后一個選項(或沒有一個選項)需要一個值:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', action='store_true')
_StoreTrueAction(option_strings=['-x'], dest='x', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('-y', action='store_true')
_StoreTrueAction(option_strings=['-y'], dest='y', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('-z')
_StoreAction(option_strings=['-z'], dest='z', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['-xyzZ'])
Namespace(x=True, y=True, z='Z')

 

2)無效參數

在解析命令行時,parse_args()檢查各種錯誤,包括不明確的選項、無效類型、無效選項、錯誤的位置參數數量等。當它遇到這樣的錯誤時,它會退出並打印錯誤以及使用信息:

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', type=int)
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=<class 'int'>, choices=None, help=None, metavar=None)
>>> parser.add_argument('bar', nargs='?')
_StoreAction(option_strings=[], dest='bar', nargs='?', const=None, default=None, type=None, choices=None, help=None, metavar=None)

1>期待值類型為int,傳入類型為string

>>> parser.parse_args(['--foo', 'spam'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: argument --foo: invalid int value: 'spam'

 

2>輸入無效的option

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', type=int)
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=<class 'int'>, choices=None, help=None, metavar=None)
>>> parser.add_argument('bar', nargs='?')
_StoreAction(option_strings=[], dest='bar', nargs='?', const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['--bar'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: unrecognized arguments: --bar

 

3>輸入參數的數量有誤,這里的參數會作為bar的參數,但是bar只接受0或1個參數

>>> parser.parse_args(['spam','badger'])
usage: PROG [-h] [--foo FOO] [bar]
PROG: error: unrecognized arguments: badger

 

3)包含-的參數

parse_args()方法嘗試在用戶明顯犯了錯誤時給出錯誤,但是有些情況本質上是模棱兩可的。

例如,命令行參數-1可以是指定選項的嘗試,也可以是提供位置參數的嘗試。parse_args()方法在這里很謹慎:如果它們看起來像負數,位置參數可能從-開始,並且解析器中沒有看起來像負數的選項,即以-開頭的選項,那么:

1> 不帶負數選項的例子:

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x')
_StoreAction(option_strings=['-x'], dest='x', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('foo', nargs='?')
_StoreAction(option_strings=[], dest='foo', nargs='?', const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('-x', '-1')

因為沒有負數選項,所以-1會被當作位置參數,而不是以-開頭的選項:

>>> parser.parse_args(['-x', '-1'])
Namespace(foo=None, x='-1')

因為沒有負數選項,所以-1,-5會被當作位置參數:

>>> parser.parse_args(['-x', '-1', '-5'])
Namespace(foo='-5', x='-1')

 

2》 帶負數選項的例子

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', nargs='?')
_StoreAction(option_strings=[], dest='foo', nargs='?', const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('-1', dest='one')
_StoreAction(option_strings=['-1'], dest='one', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

因為帶負數選項-1,所有-1會被當作選項而不是參數:

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

 

因為有負數選項,因此'-2'沒有被當成'foo'參數,而是當成一個選項,所以報沒有這個選項的錯:

>>> parser.parse_args(['-2'])
usage: PROG [-h] [-1 ONE] [foo]
PROG: error: unrecognized arguments: -2

 

這樣兩個'-1'都會被當成選項,所以會報沒有參數的錯:

>>> 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)

這樣'-f'就會被當成'foo'的參數

 

4)參數縮寫(前綴匹配)

默認情況下,parse_args()方法允許將長選項縮寫為前綴,如果縮寫沒有歧義(前綴匹配唯一選項):

即下面的例子中,'-bacon'可以縮寫成'-bac',不能縮寫成'ba',因為這樣不能區分說的是'badger'還是'bacon'

>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-bacon')
_StoreAction(option_strings=['-bacon'], dest='bacon', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('-badger')
_StoreAction(option_strings=['-badger'], dest='badger', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> 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 -bacon, -badger

對於可能產生多個選項的參數會產生錯誤。

可以通過將allow_abbrev設置為False禁用此特性。

 

5)除了 sys.argv

有時候,使用ArgumentParser解析sys.argv之外的參數可能很有用。這可以通過將字符串列表傳遞給parse_args()來實現。這對於在交互提示符下進行測試非常有用:

>>> import argparse
>>> parser = argparse.ArgumentParser()
#得到數字的最大值
>>> parser.add_argument('integers', metavar='int', type=int, choices=range(10), nargs='+', help='an integer in the range 0..9')
_StoreAction(option_strings=[], dest='integers', nargs='+', const=None, default=None, type=<class 'int'>, choices=range(0, 10), help='an integer in the range 0..9', metavar='int')
#得到數字的和
>>> parser.add_argument('--sum', dest='accumulate', action='store_const', const=sum, default=max, help='sum the integers (default: find the max)')
_StoreConstAction(option_strings=['--sum'], dest='accumulate', nargs=0, const=<built-in function sum>, default=<built-in function max>, type=None, choices=None, help='sum the integers (default: find the max)', metavar=None)
#默認使用的是求最大值,只有使用--sum指明使用的是求和
>>> 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'])
Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])

>>> parser.print_help()
usage: [-h] [--sum] int [int ...]

positional arguments:
  int         an integer in the range 0..9

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

 

6)Namespace對象

class  argparse. Namespace
  • parse_args()默認情況下使用Simple類創建一個包含屬性的對象並返回它。

這個類非常簡單,只是一個帶有可讀字符串表示的對象子類。如果你希望屬性具有類似於詞典的視圖,可以使用標准Python習語vars():

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> args = parser.parse_args(['--foo', 'BAR']) #將屬性分配給新的namespace對象
>>> args
Namespace(foo='BAR')
>>> vars(args)
{'foo': 'BAR'}

讓ArgumentParser將屬性分配給一個已經存在的對象,而不是一個新的namespace對象,這可能也很有用。這可以通過指定namespace= keyword參數來實現:

>>> class C:
...     pass
... 
>>> c = C()
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
<__main__.C object at 0x10baf6a20>
>>> c.foo
'BAR'

 

5.其他功能

1)Sub-commands子命令

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

許多程序將其功能分解為許多子命令,例如,svn程序可以調用svn checkout、svn update和svn commit等子命令。

當一個程序執行幾個不同的函數,而這些函數又需要不同類型的命令行參數時,以這種方式分割功能可能是一個特別好的主意。ArgumentParser支持使用add_subparsers()方法創建這樣的子命令。

add_subparsers()方法通常不帶參數調用,並返回一個特殊的操作對象。

這個對象只有一個方法add_parser(),它接受命令名和任何ArgumentParser構造函數參數,並返回一個可以像往常一樣修改的ArgumentParser對象。

參數描述:

  • title - help輸出中子解析器組的標題;默認情況下,如果提供description的值,則使用“subcommands”,否則使用title作為位置參數
  • description - help輸出中的子解析器組的description,默認情況下為None
  • prog - 子命令help將顯示的usage信息,默認情況下是程序的名稱和子解析器參數之前的任何位置參數
  • parser_class - 類,該類將用於創建子解析器實例,默認情況下為當前解析器的類 (e.g. ArgumentParser)
  • action - 在命令行中遇到此參數時要采取的基本操作類型
  • dest - 將存儲子命令名的屬性的名稱;默認情況下,不存儲任何值
  • help - help輸出中的子解析器組的help,默認情況下為None
  • metavar - 在help中顯示可用子命令的字符串;默認情況下,它是None,並以{cmd1, cmd2, ..}的形式顯示子命令。

舉例說明:

#創建一個頂級的解析器
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo', action='store_true', help='foo help')
_StoreTrueAction(option_strings=['--foo'], dest='foo', nargs=0, const=True, default=False, type=None, choices=None, help='foo help', metavar=None)

#在該頂級解析器基礎上生成一個子解析器對象
>>> subparsers = parser.add_subparsers(help='sub-command help')

#然后使用該子解析器對象生成一個名為'a'的解析器,並為其添加參數
>>> parser_a = subparsers.add_parser('a', help='a help')
>>> parser_a.add_argument('bar', type=int, help='bar help')
_StoreAction(option_strings=[], dest='bar', nargs=None, const=None, default=None, type=<class 'int'>, choices=None, help='bar help', metavar=None)

#然后又使用該子解析器對象生成另一個名為'b'的解析器,並為其添加參數
>>> parser_b = subparsers.add_parser('b', help='b help')
>>> parser_b.add_argument('--baz', choices='XYZ', help='baz help')
_StoreAction(option_strings=['--baz'], dest='baz', nargs=None, const=None, default=None, type=None, choices='XYZ', help='baz help', metavar=None)
#a,b兩個解析器是相互獨立的

#聲明是為解析器a傳參
>>> parser.parse_args(['a', '12'])
Namespace(bar=12, foo=False)

#設置父解析器的'--foo'的值,同時為'b'解析器傳參
>>> parser.parse_args(['--foo', 'b', '--baz', 'Z'])
Namespace(baz='Z', foo=True)

注意,parse_args()返回的對象只包含由命令行選擇的主解析器和子解析器的屬性(而不包含任何其他子解析器)。所以在上面的例子中,當a命令被指定時,只有foo和bar屬性存在,當b命令被指定時,只有foo和baz屬性存在。

類似地,當從子解析器請求幫助消息時,只會打印該特定解析器的help。help消息將不包括父解析器或兄弟解析器消息。(但是,可以通過如上所述向add_parser()提供help=參數來為每個子解析器命令提供幫助消息。)

#查看父解析器的help信息,會包括子解析器的信息
>>> 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

#查看a解析器的信息
>>> 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

#查看b解析器的信息
>>> 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()方法還支持title和description關鍵字參數。當其中之一出現時,子解析器的命令將出現在help輸出中的它們自己的組中。例如:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers(title='subcommands',description='valid subcommands',help='additional help')
>>> subparsers.add_parser('foo')
ArgumentParser(prog=' foo', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
>>> subparsers.add_parser('bar')
ArgumentParser(prog=' bar', usage=None, description=None, formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
>>> parser.parse_args(['-h'])
usage: [-h] {foo,bar} ...

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

subcommands: #title的值
  valid subcommands #description的值

  {foo,bar}   additional help #help的值

 

此外,add_parser支持一個附加的aliases參數,該參數允許多個字符串引用同一個子解析器。這個例子,像svn一樣,別名co作為checkout的縮寫:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers()
>>> checkout = subparsers.add_parser('checkout', aliases=['co'])
>>> checkout.add_argument('foo')
_StoreAction(option_strings=[], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args(['co', 'bar'])
Namespace(foo='bar')

 

處理子命令的一種特別有效的方法是將add_subparsers()方法的使用與對set_defaults()的調用結合起來,這樣每個子解析器都知道應該執行哪個Python函數。例如:

>>> def foo(args):
...     print(args.x * args.y)
... 
>>> def bar(args):
...     print('((%s))' % args.z)
... 
>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers()

#設置子解析器'foo'
>>> parser_foo = subparsers.add_parser('foo')
>>> parser_foo.add_argument('-x', type=int, default=1)
_StoreAction(option_strings=['-x'], dest='x', nargs=None, const=None, default=1, type=<class 'int'>, choices=None, help=None, metavar=None)
>>> parser_foo.add_argument('y', type=float)
_StoreAction(option_strings=[], dest='y', nargs=None, const=None, default=None, type=<class 'float'>, choices=None, help=None, metavar=None)
>>> parser_foo.set_defaults(func=foo) #設置默認使用的func為foo函數

#設置子解析器'bar'
>>> parser_bar = subparsers.add_parser('bar')
>>> parser_bar.add_argument('z')
_StoreAction(option_strings=[], dest='z', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser_bar.set_defaults(func=bar)#設置默認使用的func為bar函數
>>> 
>>> args = parser.parse_args('foo 1 -x 2'.split())
>>> args
Namespace(func=<function foo at 0x10bfd5730>, x=2, y=1.0)
>>> args.func(args) #調用的是foo函數
2.0
>>> 
>>> args = parser.parse_args('bar XYZYX'.split())
>>> args
Namespace(func=<function bar at 0x10bfd5840>, z='XYZYX')
>>> args.func(args) #調用的是bar函數
((XYZYX))

通過這種方式,您可以讓parse_args()在參數解析完成后調用適當的函數。將函數與這樣的操作關聯通常是處理每個子解析器的不同操作的最簡單方法

 

但是,如果需要檢查調用的子解析器的名稱,那么add_subparsers()調用的dest關鍵字參數將起作用:

>>> parser = argparse.ArgumentParser()
#定義的是namespace中的參數名稱
>>> subparsers = parser.add_subparsers(dest='subparser_name')

>>> subparser1 = subparsers.add_parser('1')
>>> subparser1.add_argument('-x')
_StoreAction(option_strings=['-x'], dest='x', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

>>> subparser2 = subparsers.add_parser('2')
>>> subparser2.add_argument('y')
_StoreAction(option_strings=[], dest='y', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)

>>> parser.parse_args(['2', 'frobble'])
Namespace(subparser_name='2', y='frobble') #反映在這里

 

2)FileType對象

class argparse.FileType

argparse.FileType(mode='r', bufsize=-1, encoding=None, errors=None)

FileType工廠創建可以傳遞給ArgumentParser.add_argument()的type參數的對象。將FileType對象作為其type的參數將以文件的形式打開命令行參數,這些文件具有所請求的mode模式、緩沖區大小、編碼和錯誤處理(有關詳細信息,請參閱open()函數):

>>> parser = argparse.ArgumentParser()

>>> parser.add_argument('--raw', type=argparse.FileType('wb', 0))
_StoreAction(option_strings=['--raw'], dest='raw', nargs=None, const=None, default=None, type=FileType('wb', 0), choices=None, help=None, metavar=None)

>>> parser.add_argument('out', type=argparse.FileType('w', encoding='UTF-8'))
_StoreAction(option_strings=[], dest='out', nargs=None, const=None, default=None, type=FileType('w', encoding='UTF-8'), choices=None, help=None, metavar=None)

>>> parser.parse_args(['--raw', 'raw.dat', 'file.txt'])
Namespace(out=<_io.TextIOWrapper name='file.txt' mode='w' encoding='UTF-8'>, raw=<_io.FileIO name='raw.dat' mode='wb' closefd=True>)

FileType對象理解偽參數'-',並自動將其轉換為sys.stdin用於可讀的FileType對象和sys.stdout給可寫的FileType對象:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', type=argparse.FileType('r'))
_StoreAction(option_strings=[], dest='infile', nargs=None, const=None, default=None, type=FileType('r'), choices=None, help=None, metavar=None)

>>> parser.parse_args(['-'])
Namespace(infile=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>) #說明將標准輸入作為infile的值,因為這里設置FileType('r')為'r',可讀

New in version 3.4: The encodings and errors keyword arguments.

 

3)參數組

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

默認情況下,ArgumentParser在顯示help消息時將命令行參數分組為“位置positional參數”和“可選optional參數”。當參數的概念分組比默認的更好時,可以使用add_argument_group()方法創建適當的組:

>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)
#創建了一個組
>>> group = parser.add_argument_group('group')

#添加參數到組中
>>> group.add_argument('--foo', help='foo help')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help='foo help', metavar=None)
>>> 
>>> group.add_argument('bar', help='bar help')
_StoreAction(option_strings=[], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help='bar help', metavar=None)

>>> parser.print_help()
usage: PROG [--foo FOO] bar

group:
  --foo FOO  foo help
  bar        bar help

add_argument_group()方法返回一個參數組對象,該對象具有一個add_argument()方法,就像一個常規的ArgumentParser一樣。

 

當一個參數被添加到組中時,解析器就像對待一個普通的參數一樣對待它,但是會在一個單獨的組中顯示該參數以獲取help消息。add_argument_group()方法接受title和description參數,這些參數可用於自定義這個顯示:

>>> parser = argparse.ArgumentParser(prog='PROG', add_help=False)

#設置title = 'group1', description='group1 description'
>>> group1 = parser.add_argument_group('group1', 'group1 description')
>>> group1.add_argument('foo', help='foo help')
_StoreAction(option_strings=[], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help='foo help', metavar=None)

#設置title = 'group2', description='group2 description'
>>> group2 = parser.add_argument_group('group2', 'group2 description')
>>> group2.add_argument('--bar', help='bar help')
_StoreAction(option_strings=['--bar'], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help='bar help', metavar=None)
>>> 
>>> parser.print_help()
usage: PROG [--bar BAR] foo

group1:
  group1 description

  foo        foo help

group2:
  group2 description

  --bar BAR  bar help

注意,任何不在用戶定義的組中的參數都將回到通常的“位置參數”和“可選參數”部分。

 

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')
_StoreTrueAction(option_strings=['--foo'], dest='foo', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> group.add_argument('--bar', action='store_false')
_StoreFalseAction(option_strings=['--bar'], dest='bar', nargs=0, const=False, default=True, type=None, choices=None, help=None, metavar=None)

#只有一個就能運行
>>> 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參數,以表明至少需要一個互斥參數:

>>> import argparse
>>> parser = argparse.ArgumentParser(prog='PROG')

>>> group = parser.add_mutually_exclusive_group(required=True)

>>> group.add_argument('--foo', action='store_true')
_StoreTrueAction(option_strings=['--foo'], dest='foo', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)

>>> group.add_argument('--bar', action='store_false')
_StoreFalseAction(option_strings=['--bar'], dest='bar', nargs=0, const=False, default=True, type=None, choices=None, help=None, metavar=None)

>>> parser.parse_args([]) #如果一個參數都沒有就報錯
usage: PROG [-h] (--foo | --bar)
PROG: error: one of the arguments --foo --bar is required

注意,當前互斥的參數組不支持add_argument_group()中的的title和description參數。

 

5)解析器默認值

ArgumentParser.set_defaults(**kwargs)

大多數時候,parse_args()返回的對象的屬性將通過檢查命令行參數和參數操作完全確定。

set_defaults()允許添加一些額外的屬性,這些屬性是在不檢查命令行的情況下確定的:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
_StoreAction(option_strings=[], dest='foo', nargs=None, const=None, default=None, type=<class 'int'>, choices=None, help=None, metavar=None)
>>> parser.set_defaults(bar=42, baz='badger')
>>> parser.parse_args(['736']) #命令行沒給出,但是就有了bar和baz的值
Namespace(bar=42, baz='badger', foo=736)

注意,解析器級別的默認值總是覆蓋參數級別的默認值:

>>> parser = argparse.ArgumentParser()

>>> parser.add_argument('--foo', default='bar') #參數級別的默認值
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default='bar', type=None, choices=None, help=None, metavar=None)

>>> 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')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default='badger', type=None, choices=None, help=None, metavar=None)
>>> parser.get_default('foo')
'badger'
>>> parser.set_defaults(bar='baz')
>>> parser.get_default('bar')
'baz'

 

6)打印幫助信息

在大多數典型的應用程序中,parse_args()將負責格式化和打印任何使用或錯誤消息。然而,有幾種格式化方法:

ArgumentParser.print_usage(file=None)

打印一個關於應該如何在命令行上調用ArgumentParser的簡短描述。如果文件為空,則使用sys.stdout。

ArgumentParser.print_help(file=None)

打印一條help消息,包括程序使用情況和關於ArgumentParser注冊的參數的信息。如果文件為空,則使用sys.stdout。

 

這些方法也有一些變體,它們只是返回一個字符串,而不是打印它:

ArgumentParser.format_usage()

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

ArgumentParser.format_help()

返回一個包含幫助消息的字符串,包括程序使用情況和關於ArgumentParser注冊的參數的信息。

舉例:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default='badger')
_StoreAction(option_strings=['--foo'], dest='foo', nargs=None, const=None, default='badger', type=None, choices=None, help=None, metavar=None)
>>> parser.get_default('foo')
'badger'
>>> parser.set_defaults(bar='baz')
>>> parser.get_default('bar')
'baz'

>>> parser.print_usage()
usage: [-h] [--foo FOO]

>>> parser.print_help()
usage: [-h] [--foo FOO]

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

>>> parser.format_usage()
'usage: [-h] [--foo FOO]\n'

>>> parser.format_help()
'usage: [-h] [--foo FOO]\n\noptional arguments:\n  -h, --help  show this help message and exit\n  --foo FOO\n'

 

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')
_StoreTrueAction(option_strings=['--foo'], dest='foo', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('bar')
_StoreAction(option_strings=[], dest='bar', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
>>> parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam'])
(Namespace(bar='BAR', foo=True), ['--badger', 'spam'])

⚠️警告:前綴匹配規則適用於parse_known_args()。解析器可能會使用一個選項,即使它只是它的一個已知選項的前綴,而不是將它留在剩余的arguments列表中。

 

8)定制文件解析

ArgumentParser.convert_arg_line_to_args(arg_line)

從文件中讀取的參數(請參閱fromfile_prefix_chars關鍵字參數到ArgumentParser構造函數)是從每一行讀取一個參數。convert_arg_line_to_args()可以被覆蓋,以便更好地閱讀。

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

此方法的一個有用覆蓋是將每個空格分隔的單詞作為一個參數。下面的例子演示了如何做到這一點:

class MyArgumentParser(argparse.ArgumentParser):
    def convert_arg_line_to_args(self, arg_line):
        return arg_line.split()

 

9)Exiting methods存在方法

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

此方法終止程序,以指定的狀態退出,如果給定,則在此之前打印一條消息。

ArgumentParser.error(message)

此方法將一個usage消息(包括發送給標准錯誤的消息)打印出來,並使用狀態代碼2終止程序。

 


免責聲明!

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



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