argparse --- 命令行選項、參數和子命令解析器?

3.2 新版功能.

源代碼: Lib/argparse.py


argparse 模塊可以讓人輕松編寫用戶友好的命令行接口。程序定義它需要的參數,然后 argparse 將弄清如何從 sys.argv 解析出那些參數。 argparse 模塊還會自動生成幫助和使用手冊,并在用戶給程序傳入無效參數時報出錯誤信息。

示例?

以下代碼是一個 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'

以下部分將引導你完成這個示例。

創建一個解析器?

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

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

ArgumentParser 對象包含將命令行解析成 Python 數據類型所需的全部信息。

添加參數?

給一個 ArgumentParser 添加程序參數信息是通過調用 add_argument() 方法完成的。通常,這些調用指定 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 屬性將是一個包含一個或多個整數的列表,而 accumulate 屬性當命令行中指定了 --sum 參數時將是 sum() 函數,否則則是 max() 函數。

解析參數?

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 中確定命令行參數。

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

  • allow_abbrev - 如果縮寫是無歧義的,則允許縮寫長選項 (默認值:True

在 3.5 版更改: 增加了 allow_abbrev 參數。

以下部分描述這些參數如何使用。

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= 參數確定的程序名稱,都可以在幫助消息里通過 %(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

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 格式說明符來填入程序名稱。

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

在默認情況下,description 將被換行以便適應給定的空間。如果想改變這種行為,見 formatter_class 參數。

epilog?

一些程序喜歡在 description 參數后顯示額外的對程序的描述。這種文字能夠通過給 ArgumentParser:: 提供 epilog= 參數而被指定。

>>> 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= text 在默認情況下會換行,但是這種行為能夠被調整通過提供 formatter_class 參數給 ArgumentParse.

parents?

有些時候,少數解析器會使用同一系列參數。 單個解析器能夠通過提供 parents= 參數給 ArgumentParser 而使用相同的參數而不是重復這些參數的定義。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 . 否則, ArgumentParse 將會看到兩個 -h/--help 選項(一個在父參數中一個在子參數中)并且產生一個錯誤。

注解

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

formatter_class?

ArgumentParser 對象允許通過指定備用格式化類來自定義幫助格式。目前,有四種這樣的類。

class argparse.RawDescriptionHelpFormatter?
class argparse.RawTextHelpFormatter?
class argparse.ArgumentDefaultsHelpFormatter?
class argparse.MetavarTypeHelpFormatter?

RawDescriptionHelpFormatterRawTextHelpFormatter 在正文的描述和展示上給與了更多的控制。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

RawDescriptionHelpFormatterformatter_class= 表示 descriptionepilog 已經被正確的格式化了,不能在命令行中被自動換行:

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

MetavarTypeHelpFormatter 為它的值在每一個參數中使用 type 的參數名當作它的顯示名(而不是使用通常的格式 dest ):

>>> parser = argparse.ArgumentParser(
...     prog='PROG',
...     formatter_class=argparse.MetavarTypeHelpFormatter)
>>> parser.add_argument('--foo', type=int)
>>> parser.add_argument('bar', type=float)
>>> parser.print_help()
usage: PROG [-h] [--foo int] float

positional arguments:
  float

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

prefix_chars?

許多命令行會使用 - 當作前綴,比如 -f/--foo。如果解析器需要支持不同的或者額外的字符,比如像 +f 或者 /foo 的選項,可以在參數解析構建器中使用 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 選項不被允許。

fromfile_prefix_chars?

有些時候,先舉個例子,當處理一個特別長的參數列表的時候,把它存入一個文件中而不是在命令行打出來會很有意義。如果 fromfile_prefix_chars= 參數提供給 ArgumentParser 構造函數,之后所有類型的字符的參數都會被當成文件處理,并且會被文件包含的參數替代。舉個栗子:

>>> 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,意味著參數不會被當作文件對待。

argument_default?

一般情況下,參數默認會通過設置一個默認到 add_argument() 或者調用帶一組指定鍵值對的 ArgumentParser.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()

allow_abbrev?

正常情況下,當你向 ArgumentParserparse_args() 方法傳入一個參數列表時,它會 recognizes abbreviations

這個特性可以設置 allow_abbrevFalse 來關閉:

>>> parser = argparse.ArgumentParser(prog='PROG', allow_abbrev=False)
>>> parser.add_argument('--foobar', action='store_true')
>>> parser.add_argument('--foonley', action='store_false')
>>> parser.parse_args(['--foon'])
usage: PROG [-h] [--foobar] [--foonley]
PROG: error: unrecognized arguments: --foon

3.5 新版功能.

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 選項字符串被重寫。

add_help?

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

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

如果 -h or --help 在命令行中被提供, 參數解析器幫助信息會打印:

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

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

有時候可能會需要關閉額外的幫助信息。這可以通過在 ArgumentParser 中設置 add_help= 參數為 False 來實現。

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

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() 所返回對象上的屬性名。

以下部分描述這些參數如何使用。

name or flags?

add_argument() 方法必須知道它是否是一個選項,例如 -f--foo,或是一個位置參數,例如一組文件名。第一個傳遞給 add_argument() 的參數必須是一系列 flags 或者是一個簡單的參數名。例如,可以選項可以被這樣創建:

>>> 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: the following arguments are required: bar

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 命名參數指定的值。 'store_const' 動作通常用在選項中來指定一些標志。例如:

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--foo', action='store_const', const=42)
    >>> parser.parse_args(['--foo'])
    Namespace(foo=42)
    
  • 'store_true' and 'store_false' - 這些是 'store_const' 分別用作存儲 TrueFalse 值的特殊用例。另外,它們的默認值分別為 FalseTrue。例如:

    >>> 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(foo=True, bar=False, baz=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=[<class 'str'>, <class 'int'>])
    
  • 'count' - 計算一個關鍵字參數出現的數目或次數。例如,對于一個增長的詳情等級來說有用:

    >>> parser = argparse.ArgumentParser()
    >>> parser.add_argument('--verbose', '-v', action='count', default=0)
    >>> parser.parse_args(['-vvv'])
    Namespace(verbose=3)
    

    請注意,default 將為 None,除非顯式地設為 0。

  • '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 子類或實現相同接口的其他對象來指定任意操作。建議的方法是擴展 Action,覆蓋 __call__ 方法和可選的 __init__ 方法。

一個自定義動作的例子:

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

更多描述,見 Action。

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'])
    Namespace(bar='XX', foo='YY')
    >>> parser.parse_args(['XX', '--foo'])
    Namespace(bar='XX', foo='c')
    >>> parser.parse_args([])
    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=<_io.TextIOWrapper name='input.txt' encoding='UTF-8'>,
              outfile=<_io.TextIOWrapper name='output.txt' encoding='UTF-8'>)
    >>> parser.parse_args([])
    Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>,
              outfile=<_io.TextIOWrapper name='<stdout>' encoding='UTF-8'>)
    
  • '*'。所有當前命令行參數被聚集到一個列表中。注意通過 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'])
    Namespace(foo=['a', 'b'])
    >>> parser.parse_args([])
    usage: PROG [-h] foo [foo ...]
    PROG: error: the following arguments are required: foo
    
  • argarse.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 決定。通常這意味著單一項目(非列表)消耗單一命令行參數。

const?

add_argument() 的``const`` 參數用于保存不從命令行中讀取但被各種 ArgumentParser 動作需求的常數值。最常用的兩例為:

  • add_argument() 通過 action='store_const'action='append_const 調用時。這些動作將 const 值添加到 parse_args() 返回的對象的屬性中。在 action 的描述中查看案例。

  • add_argument() 通過選項(例如 -f--foo)調用并且 nargs='?' 時。這會創建一個可以跟隨零個或一個命令行參數的選項。當解析命令行時,如果選項后沒有參數,則將用 const 代替。在 nargs 描述中查看案例。

'store_const''append_const' 動作, const 命名參數必須給出。對其他動作,默認為 None。

默認值?

所有選項和一些位置參數可能在命令行中被忽略。add_argument() 的命名參數 default,默認值為 None,指定了在命令行參數未出現時應當使用的值。對于選項, default 值在選項未在命令行中出現時使用:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args(['--foo', '2'])
Namespace(foo='2')
>>> parser.parse_args([])
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'])
Namespace(foo='a')
>>> parser.parse_args([])
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')

type -- 類型?

默認情況下,ArgumentParser 對象將命令行參數當作簡單字符串讀入。然而,命令行字符串經常需要被當作其它的類型,比如 float 或者 intadd_argument()type 關鍵詞參數允許任何的類型檢查和類型轉換。一般的內建類型和函數可以直接被 type 參數使用。

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', type=int)
>>> parser.add_argument('bar', type=open)
>>> parser.parse_args('2 temp.txt'.split())
Namespace(bar=<_io.TextIOWrapper name='temp.txt' encoding='UTF-8'>, foo=2)

type 參數被應用到默認參數時,請參考 default 參數的部分。

為方便使用不同類型的文件,argparse 模塊提供了 FileType 工廠類,該類接受 mode=, bufsize=, encoding=errors=open() 函數參數。 例如,FileType('w') 可被用來創建一個可寫文件:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar', type=argparse.FileType('w'))
>>> parser.parse_args(['out.txt'])
Namespace(bar=<_io.TextIOWrapper name='out.txt' encoding='UTF-8'>)

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'])
Namespace(foo=9)
>>> parser.parse_args(['7'])
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=range(5, 10))
>>> parser.parse_args(['7'])
Namespace(foo=7)
>>> parser.parse_args(['11'])
usage: PROG [-h] {5,6,7,8,9}
PROG: error: argument foo: invalid choice: 11 (choose from 5, 6, 7, 8, 9)

詳情請查閱 choices 段落。

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 對象,自定義容器等都是受支持的。

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() 將會報告一個錯誤。

注解

必需的選項通常被認為是不適宜的,因為用戶會預期 options 都是 可選的,因此在可能的情況下應當避免使用它們。

help?

help 值是一個包含參數簡短描述的字符串。 當用戶請求幫助時(一般是通過在命令行中使用 -h--help 的方式),這些 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'])
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

由于幫助字符串支持 %-formatting,如果你希望在幫助字符串中顯示 % 字面值,你必須將其轉義為 %%。

argparse 支持靜默特定選項的幫助,具體做法是將 help 的值設為 argparse.SUPPRESS:

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

metavar?

ArgumentParser 生成幫助消息時,它需要用某種方式來引用每個預期的參數。 默認情況下,ArgumentParser 對象使用 dest 值作為每個對象的 "name"。 默認情況下,對于位置參數動作,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

dest?

大多數 ArgumentParser 動作會添加一些值作為 parse_args() 所返回對象的一個屬性。 該屬性的名稱由 add_argument()dest 關鍵字參數確定。 對于位置參數動作,dest 通常會作為 add_argument() 的第一個參數提供:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
>>> parser.parse_args(['XXX'])
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')

Action 類?

Action 類實現了 Action API,它是一個返回可調用對象的可調用對象,返回的可調用對象可處理來自命令行的參數。 任何遵循此 API 的對象均可作為 action 形參傳給 add_argument()。

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

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

Action 的實例(或作為or return value of any callable to the action 形參的任何可調用對象的返回值)應當定義 "dest", "option_strings", "default", "type", "required", "help" 等屬性。 確保這些屬性被定義的最容易方式是調用 Action.__init__

Action 的實例應當為可調用對象,因此所有子類都必須重載 __call__ 方法,該方法應當接受四個形參:

  • parser - 包含此動作的 ArgumentParser 對象。

  • namespace - 將由 parse_args() 返回的 Namespace 對象。 大多數動作會使用 setattr() 為此對象添加屬性。

  • values - 已關聯的命令行參數,并提供相應的類型轉換。 類型轉換由 add_argument()type 關鍵字參數來指定。

  • option_string - 被用來發起調用此動作的選項字符串。 option_string 參數是可選的,且此參數在動作關聯到位置參數時將被略去。

__call__ 方法可以執行任意動作,但通常將基于 destvalues 來設置 namespace 的屬性。

parse_args() 方法?

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

將參數字符串轉換為對象并將其設為命名空間的屬性。 返回帶有成員的命名空間。

之前對 add_argument() 的調用決定了哪些對象被創建以及它們如何被賦值。 請參閱 add_argument() 的文檔了解詳情。

  • args - 要解析的字符串列表。 默認情況下是從 sys.argv 獲取。

  • namespace - 用于獲取屬性的對象。 默認值是一個新的空 Namespace 對象。

選項值語法?

parse_args() 方法支持多種指定選項值的方式(如果它接受選項的話)。 在最簡單的情況下,選項和它的值是作為兩個單獨參數傳入的:

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

對于長選項(名稱長度超過一個字符的選項),選項和值也可以作為單個命令行參數傳入,使用 = 分隔它們即可:

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

對于短選項(長度只有一個字符的選項),選項和它的值可以拼接在一起:

>>> parser.parse_args(['-xX'])
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'])
Namespace(x=True, y=True, z='Z')

無效的參數?

在解析命令行時,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

包含 - 的參數?

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)

參數縮寫(前綴匹配)?

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

可產生一個以上選項的參數會引發錯誤。 此特定可通過將 allow_abbrev 設為 False 來禁用。

sys.argv 以外?

有時在 sys.argv 以外用 ArgumentParser 解析參數也是有用的。 這可以通過將一個字符串列表傳給 parse_args() 來實現。 它適用于在交互提示符下進行檢測:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument(
...     'integers', metavar='int', type=int, choices=range(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'])
Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])

命名空間對象?

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:
...     pass
...
>>> c = C()
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
>>> c.foo
'BAR'

其它實用工具?

子命令?

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

許多程序都會將其功能拆分為一系列子命令,例如,svn 程序包含的子命令有 svn checkout, svn updatesvn commit。 當一個程序能執行需要多組不同種類命令行參數時這種拆分功能的方式是一個非常好的主意。 ArgumentParser 通過 add_subparsers() 方法支持創建這樣的子命令。 add_subparsers() 方法通常不帶參數地調用并返回一個特殊的動作對象。 這種對象只有一個方法 add_parser(),它接受一個命令名稱和任意多個 ArgumentParser 構造器參數,并返回一個可以通常方式進行修改的 ArgumentParser 對象。

形參的描述

  • title - 輸出幫助的子解析器分組的標題;如果提供了描述則默認為 "subcommands",否則使用位置參數的標題

  • description - 輸出幫助中對子解析器的描述,默認為 None

  • prog - 將與子命令幫助一同顯示的用法信息,默認為程序名稱和子解析器參數之前的任何位置參數。

  • parser_class - 將被用于創建子解析器實例的類,默認為當前解析器類(例如 ArgumentParser)

  • action - 當此參數在命令行中出現時要執行動作的基本類型

  • dest - 將被用于保存子命令名稱的屬性名;默認為 None 即不保存任何值

  • required - 是否必須要提供子命令,默認為 False (在 3.7 中新增)

  • 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_parser 還支持附加的 aliases 參數,它允許多個字符串指向同一子解析器。 這個例子類似于 svn,將別名 co 設為 checkout 的縮寫形式:

>>> parser = argparse.ArgumentParser()
>>> subparsers = parser.add_subparsers()
>>> checkout = subparsers.add_parser('checkout', aliases=['co'])
>>> checkout.add_argument('foo')
>>> parser.parse_args(['co', 'bar'])
Namespace(foo='bar')

一個特別有效的處理子命令的方式是將 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() 執行調用適當函數的任務。 像這樣將函數關聯到動作通常是你處理每個子解析器的不同動作的最簡便方式。 但是,如果有必要檢查被發起調用的子解析器的名稱,則 add_subparsers() 調用的 dest 關鍵字參數將可實現:

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

在 3.7 版更改: 新增 required 關鍵字參數。

FileType 對象?

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

FileType 工廠類用于創建可作為 ArgumentParser.add_argument() 的 type 參數傳入的對象。 以 FileType 對象作為其類型的參數將使用命令行參數以所請求模式、緩沖區大小、編碼格式和錯誤處理方式打開文件(請參閱 open() 函數了解詳情):

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--raw', type=argparse.FileType('wb', 0))
>>> parser.add_argument('out', type=argparse.FileType('w', encoding='UTF-8'))
>>> 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'>)

FileType 對象能理解偽參數 '-' 并會自動將其轉換為 sys.stdin 用于可讀的 FileType 對象,或是 sys.stdout 用于可寫的 FileType 對象:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('infile', type=argparse.FileType('r'))
>>> parser.parse_args(['-'])
Namespace(infile=<_io.TextIOWrapper name='<stdin>' encoding='UTF-8'>)

3.4 新版功能: encodingserrors 關鍵字參數。

參數組?

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() 方法返回一個具有 add_argument() 方法的參數分組對象,這與常規的 ArgumentParser 一樣。 當一個參數被加入分組時,解析器會將它視為一個正常的參數,但是會在不同的幫助消息分組中顯示該參數。 add_argument_group() 方法接受 titledescription 參數,它們可被用來定制顯示內容:

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

請注意任意不在你的自定義分組中的參數最終都將回到通常的“位置參數”和“可選參數”分組中。

互斥?

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()titledescription 參數。

解析器默認值?

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

獲取一個命名空間屬性的默認值,該值是由 add_argument()set_defaults() 設置的:

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

打印幫助?

在大多數典型應用中,parse_args() 將負責任何用法和錯誤消息的格式化和打印。 但是,也可使用某些其他格式化方法:

ArgumentParser.print_usage(file=None)?

打印一段簡短描述,說明應當如何在命令行中發起調用 ArgumentParser。 如果 fileNone,則默認使用 sys.stdout

ArgumentParser.print_help(file=None)?

打印一條幫助消息,包括程序用法和通過 ArgumentParser 注冊的相關參數信息。 如果 fileNone,則默認使用 sys.stdout。

還存在這些方法的幾個變化形式,它們只返回字符串而不打印消息:

ArgumentParser.format_usage()?

返回一個包含簡短描述的字符串,說明應當如何在命令行中發起調用 ArgumentParser。

ArgumentParser.format_help()?

反回一個包含幫助消息的字符串,包括程序用法和通過 ArgumentParser 注冊的相關參數信息。

部分解析?

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

有時一個腳本可能只解析部分命令行參數,而將其余的參數繼續傳遞給另一個腳本或程序。 在這種情況下,parse_known_args() 方法會很有用處。 它的作用方式很類似 parse_args() 但區別在于當存在額外參數時它不會產生錯誤。 而是會返回一個由兩個條目構成的元組,其中包含帶成員的命名空間和剩余參數字符串的列表。

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

警告

前綴匹配 規則應用于 parse_known_args()。 一個選項即使只是已知選項的前綴部分解析器也能識別該選項,不會將其放入剩余參數列表。

自定義文件解析?

ArgumentParser.convert_arg_line_to_args(arg_line)?

從文件讀取的參數(見 ArgumentParserfromfile_prefix_chars 關鍵字參數)將是一行讀取一個參數。 convert_arg_line_to_args() 可被重載以使用更復雜的讀取方式。

此方法接受從參數文件讀取的字符串形式的單個參數 arg_line。 它返回從該字符串解析出的參數列表。 此方法將在每次按順序從參數文件讀取一行時被調用一次。

此方法的一個有用的重載是將每個以空格分隔的單詞視為一個參數。 下面的例子演示了如何實現此重載:

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

退出方法?

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

此方法將終結程序,附帶指定的 status 退出,并且如果給出了 message 則會在退出前將其打印輸出。

ArgumentParser.error(message)?

此方法將向標準錯誤打印包括 message 的用法消息并附帶狀態碼 2 終結程序。

混合解析?

ArgumentParser.parse_intermixed_args(args=None, namespace=None)?
ArgumentParser.parse_known_intermixed_args(args=None, namespace=None)?

許多 Unix 命令允許用戶混用可選參數與位置參數。 parse_intermixed_args()parse_known_intermixed_args() 方法均支持這種解析風格。

這些解析器并不支持所有的 argparse 特性,并且當未支持的特性被使用時將會引發異常。 特別地,子解析器,argparse.REMAINDER 以及同時包括可選與位置參數的互斥分組是不受支持的。

下面的例子顯示了 parse_known_args()parse_intermixed_args() 之間的差異:前者會將 ['2', '3'] 返回為未解析的參數,而后者會將所有位置參數收集至 rest 中。

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.add_argument('cmd')
>>> parser.add_argument('rest', nargs='*', type=int)
>>> parser.parse_known_args('doit 1 --foo bar 2 3'.split())
(Namespace(cmd='doit', foo='bar', rest=[1]), ['2', '3'])
>>> parser.parse_intermixed_args('doit 1 --foo bar 2 3'.split())
Namespace(cmd='doit', foo='bar', rest=[1, 2, 3])

parse_known_intermixed_args() 返回由兩個條目組成的元組,其中包含帶成員的命名空間以及剩余參數字符串列表。 當存在任何剩余的未解析參數字符串時 parse_intermixed_args() 將引發一個錯誤。

3.7 新版功能.

升級 optparse 代碼?

起初,argparse 曾經嘗試通過 optparse 來維持兼容性。 但是,optparse 很難透明地擴展,特別是那些為支持新的 nargs= 描述方式和更好的用法消息所需的修改。當When most everything in optparse 中幾乎所有內容都已被復制粘貼或打上補丁時,維持向下兼容看來已是不切實際的。

argparse 模塊在許多方面對標準庫的 optparse 模塊進行了增強,包括:

  • 處理位置參數。

  • 支持子命令。

  • 允許替代選項前綴例如 +/。

  • 處理零個或多個以及一個或多個風格的參數。

  • 生成更具信息量的用法消息。

  • 提供用于定制 typeaction 的更為簡單的接口。

optparseargparse 的部分升級路徑:

  • 將所有 optparse.OptionParser.add_option() 調用替換為 ArgumentParser.add_argument() 調用。

  • (options, args) = parser.parse_args() 替換為 args = parser.parse_args() 并為位置參數添加額外的 ArgumentParser.add_argument() 調用。 請注意之前所謂的 optionsargparse 上下文中被稱為 args。

  • 通過使用 parse_intermixed_args() 而非 parse_args() 來替換 optparse.OptionParser.disable_interspersed_args()。

  • 將回調動作和 callback_* 關鍵字參數替換為 typeaction 參數。

  • type 關鍵字參數字符串名稱替換為相應的類型對象(例如 int, float, complex 等)。

  • optparse.Values 替換為 Namespace 并將 optparse.OptionErroroptparse.OptionValueError 替換為 ArgumentError

  • 將隱式參數字符串例如使用標準 Python 字典語法的 %default%prog 替換為格式字符串,即 %(default)s%(prog)s

  • 將 OptionParser 構造器 version 參數替換為對 parser.add_argument('--version', action='version', version='<the version>') 的調用。