python argparse:命令列引數解析詳解
阿新 • • 發佈:2019-11-05
## 簡介
本文介紹的是***[argparse](https://docs.python.org/3/library/argparse.html)***模組的基本使用方法,尤其詳細介紹**add_argument**內建方法各個引數的使用及其效果。
本文翻譯自[argparse的官方說明](https://docs.python.org/3/library/argparse.html),並加上一些筆者的理解
```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))
```
如上示例,*argparse*模組的基本使用包含5個步驟:
1. import模組:*import argparse*
2. 獲解析器物件:*argparse.ArgumentParser*
3. 利用解析器物件內建方法,新增引數解析規則:*add_argument*
4. 利用解析器物件內建方法,開始解析引數,獲取解析結果物件:*parse_args*
5. 從解析結果物件中,獲取引數值:*parse_args*
## 解析器類(ArgumentParser)
在第2步中,我們通過```ArgumentParser()```函式的呼叫獲取瞭解析器物件```ArgumentParser```。
在瞭解解析器物件的各個成員之前,我們先對一段正常的說明文字進行區間劃分
```
# usage欄位
usage: 程式名 [-h|--help] .....
# Description欄位
程式功能描述
# 位置引數說明(必選)
positional arguments:
...
# 可選引數說明
optional arguments:
...
# 補充說明欄位
...
```
例如
```
usage: PROG [-h] [--foo [FOO]] bar [bar ...]
bar help
positional arguments:
bar bar help
optional arguments:
-h, --help show this help message and exit
--foo [FOO] foo help
And that's how you'd foo a bar
```
*關於位置引數與可選引數的理解,參考下一章節:[新增引數解析規則](#關鍵字name-or-flags)*
在上述的區間劃的認識下,我們再來看看解析器物件的成員及其功能
| 名字 | 預設值 | 功能 |
| :---: | :---: | :--- |
| prog | sys.argv[0] | ```-h```時顯示的程式名 |
| usage | - | usage欄位描述 |
| description | None | description欄位描述 |
| epilog | None | 補充欄位描述 |
| parents | None | 從父(公共)解析器中繼承所有的引數選項 |
| formatter_class | None | 定製說明文字的顯示風格 |
| prefix_class | - | 定製字首字元,例如字首**"-b"**改為**“+b"** |
| add_help | True | 是否使能顯示引數 ```-h --help``` |
| allow_abbrev | True | 是否支援長引數 |
| fromfile_prefix_chars | None | 略 |
| argument_default | None | 略 |
| conflict_handler | None | 略 |
比較常用的是***description***,例如:
```
parser = argparse.ArgumentParser(description='Process some integers.')
```
或者
```
parser = argparse.ArgumentParser()
parser.descritpioin="Process some integers."
```
## 新增引數解析規則(add_argument)
***add_argument***是解析器類***ArgumentParser***的內建方法,用於向解析器新增引數解析規則
```
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type]
[, choices][, required][, help][, metavar][, dest])
```
內建方法支援以下的**關鍵字**,我們會對每一個關鍵字及其效果做進一步說明
| 關鍵字 | 簡介 |
| :--- | :---- |
| [name or flags](#關鍵字name-or-flags) | 引數名或者"-/--"開頭的選項,例如```foo```或者```-f, --foo``` |
| [action](#關鍵字action) | 匹配到選項後的行為 |
| [nargs](#關鍵字nargs) | 選項跟隨的引數個數 |
| [const](#關鍵字const) | 在某些```action```和```nargs```下,使用的固定值 |
| [default](#關鍵字default) | 預設值 |
| [type](#關鍵字type) | 引數型別 |
| [choices](#關鍵字choices) | 可選的引數值範圍 |
| [required](#關鍵字required) | 選項必選or可選 |
| [help](#關鍵字help) | 引數描述 |
| [metavar](#關鍵字metavar) | 使用說明中顯示的引數名 |
| [dest](#關鍵字dest) | 選項最終在解析結果物件中的名字 |
### 關鍵字name or flags
**關鍵字name**是什麼?**flags**又是什麼?兩者有什麼差別?
**name表示引數名,其賦值與位置順序相關,因此也叫位置引數名,命令列中必須賦值**
**flags表示```-|--```開頭的引數名,命令列中可選引數**
例如:
```
#可選的flags引數
parser.add_argument('-f', '--foo')
#必選的name位置引數
parser.add_argument('bar0')
parser.add_argument('bar1')
```
這裡假設```--foo```需要帶1個引數,那麼
```
prog arg1 --foo arg2 arg3
```
* arg1 是位置引數bar0的值
* arg2 是可選引數'-f, --foo'的值
* arg3 是位置引數bar1的值
換句話來說,在輸入的命令列中,除去所有```-|--```開頭的引數及其帶上的引數值之外,剩下的引數都為位置引數,其順序依次對應使用*add_argument*註冊的位置引數順序。
**在命令列呼叫中,位置引數必須賦值,即每個必選引數都要有賦值;而可選引數```(-|--)```可根據需求選擇**
### 關鍵字action
功能如其名,**關鍵字action**控制匹配到命令列選項後的行為。引數解析後不是儲存值就好了?我們繼續看看。
**關鍵字action**只支援以下值,我們稍後再詳細講解每一個值的含義:
| 值 | 含義 |
| :--- | :--- |
| store | 儲存引數值 |
| store_const | 與**關鍵字const**配合使用,儲存**關鍵字const**的值 |
| store_true | 儲存值為*True* |
| store_false | 儲存值為*False* |
| append | 儲存多次選項值為列表 |
| append_const | 與**關鍵字const**配合使用,儲存**關鍵字const**的值為列表 |
| const | 儲存選項的出現次數 |
| help | 效果等效於```-h```和 ```--help``` |
| version | 列印版本 |
#### store
儲存引數值,這也是預設的行為,我們看個例子:
```python
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.parse_args('--foo 1'.split())
Namespace(foo='1')
```
在```parse_args()```之後,```--foo```選項的值就儲存到了```parse_args()```的解析結果物件中。
我們可以這樣獲取解析結果物件的值:
```python
args = parser.parse_args('--foo 1'.split())
print(args.foo)
```
總結來說,**選項名成為了解析結果物件的成員,而選項對應的值則成了成員的值**
到這裡,我們存在2個疑惑:
1. 當同時支援```-f```和```--foo```時,生成的成員名是什麼呢?能自定義名字麼?
2. 當```PROG -f```這樣不需要帶引數的選項,儲存的成員值是什麼樣的呢?
不用急,我們繼續往下看
#### store_const
在匹配到選項後,儲存[**關鍵字const**](#關鍵字const)的值,常用於命令列中不帶引數的選項。例如:
```python
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='store_const', const=42)
>>> parser.parse_args(['--foo'])
Namespace(foo=42)
```
從上面的例子,我們可以看到,在匹配到```--foo```後,對應成員foo的儲存為了```const引數```的值。
但更多時候,我們不帶引數的選項更多隻是表示布林型的開關,這時候我們可用```store_true```或者```store_false```
#### store_true 和 store_false
```store_true```和```store_false```是一種特殊的```store_const```,儲存的值型別為布林型```True```或```False```。例如:
```python
>>> 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)
```
示例中有3個布林型“開關”,可以發現有以下特點:
1. ```store_true```在匹配到命令選項後,儲存為```True```;相對的,```store_false```儲存為```False```
2. 當命令列中沒匹配到開關後,例如示例中的```baz```,則儲存為```store_false```的相反值```True```
#### append
把所有值儲存為一個列表,常用於支援多次選項的情況,例如:
```python
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', action='append')
>>> parser.parse_args('--foo 1 --foo 2'.split())
Namespace(foo=['1', '2'])
```
#### append_const
與```store_const```非常相似,只是把值儲存為一個列表。此時如果沒有指定**關鍵字const**,則預設為```None```。```append_const```常用於多個不同選項值需要儲存到相同成員列表的情況。例如:
```python
>>> 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=[, ])
```
理解上文需要知道以下前提:
1. [**關鍵字dest**](#關鍵字dest)用於指定成員名
2. 引數的值可以是各種物件,包括型別物件,即示例中的**str型別**和**int型別**
在示例中,```--str```的常量值是***str型別***,以列表形式儲存到**types成員**;```--int```的常量值是***int型別***,以列表形式儲存到**types成員**
#### count
如果我們只需要統計**選項**出現的次數,此處可以用```count```,例如:
```python
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--verbose', '-v', action='count')
>>> parser.parse_args(['-vvv'])
Namespace(verbose=3)
```
#### help
列印幫助資訊,功能等效於```-h|--help```
#### version
列印版本資訊,需要配合**關鍵字version**使用,例如:
```python
>>> 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
```
### 關鍵字nargs
**關鍵字nargs**是*number argumemts*的縮寫,表示選項有多少個引數,其支援以下值:
| 值 | 含義 |
| :---: | :--- |
| N (an integer) | 收集N個引數到列表 |
| '?' | 無引數或單個引數 |
| '*' | 大於等於0個引數 |
| '+' | 大於等於1個引數 |
| argparse.REMAINDER | 只收集不解析 |
當沒有指定**關鍵字nargs**時,其實際的值取決於**關鍵字action**,例如當```action = "store"```時,預設獲取1個引數,當```action = "store_true"```時,選項不需要帶引數。
#### N (an integer)
此處的```N```,表示一個整型數字,含義為選項需要提供N個引數。例如:
```python
>>> 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```時,其並不等效於**關鍵字nargs**的預設情況。例如:
```python
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar0', nargs=1)
>>> parser.add_argument('bar1')
>>> parser.parse_args('a b'.split())
Namespace(bar0=['a'], bar1='b')
```
可以發現,```nargs = 1```時,例如bar0,其值是一個列表,一個只有1個元素的列表;而預設情況下,就是一個元素,官方稱為```item```。
#### '?'
```nargs='?'```可以實現3種場景:
1. 輸入的命令列中,選項帶引數時,值為附帶的引數
2. 輸入的命令列中,沒有改選項時,值為**關鍵字default**的值
3. 輸入的命令列中,有選項但沒帶引數時,值為**關鍵字const**的值(只適用於可選選項(flag))
例如:
```python
>>> 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')
```
一個更常用的場景,是實現可選的輸入輸出檔案,例如:
```python
>>> 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='' encoding='UTF-8'>,
outfile=<_io.TextIOWrapper name='' encoding='UTF-8'>)
```
上述例子中,如果命令列沒有指定input,則使用標準輸入stdin;如果命令列沒有指定output,則使用標準輸出stdout
#### '*'
```nargs=2```會限制一定要有2個引數,如果需要任意多個引數呢?我們可以用```nargs='*'```,例如:
```python
>>> 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'])
```
與```nargs=N```相似,最終的值是列表型別。
#### '+'
```nargs='+'```與```nargs='*'```從功能上非常相似,唯一不同的地方在於,```nargs='+'```要求至少要有1個引數,否則會報錯。
```'?'```,```'+'```與```'*'```的定義與正則表示式中的```?```,```+```和```*```非常相似
在正則表示式中,
* ?:表示0或1個字元
* +:表示大於等於1個字元
* *:表示大於等於0個字元
我們看個例子:
```python
>>> 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
```
#### argparse.REMAINDER
```nargs=argparse.REMAINDER```常用於收集引數後傳遞給其他的命令列解析工具,其不會解析```-|--```,只是收集所有選項到列表。
例如:
```python
>>> 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')
```
上例中,**argparse**沒有解析```args```選項的```--arg1```,而是全部收集到了一個列表
### 關鍵字const
在**關鍵字acton**和**關鍵字nargs**中,其實已經涉及了**關鍵字const**的所有功能。
**關鍵字const**只是儲存一個常量值,在以下兩種情況下才會使用:
1. [```action='store_const'```](#store_const)或者[```action='append_const'```](#sppend_const)
2. [```nargs='?'```](#'?')
當使用```action='store_const'```和```action='append_const'```時,**關鍵字const**必須提供,對其他的**action關鍵字**時,預設值為```None```
### 關鍵字default
有時候,選項不帶引數,或者命令列沒對應選項,這時候就可以使用預設值,而**關鍵字default**儲存的就是預設值。預設情況下,**關鍵字default**的值為```None```。例如:
```python
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=42)
>>> parser.parse_args(['--foo', '2'])
Namespace(foo='2')
>>> parser.parse_args([])
Namespace(foo=42)
```
如果**關鍵字default**賦值的是字串,而**關鍵字type**有指定引數型別,那麼就會把字串轉為**關鍵字type**指定的型別,例如:
```python
>>> 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**](#關鍵字nargs)為```?```或者```*```,那麼default的值會在命令列沒有引數時使用,例如:
```python
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('foo', nargs='?', default=42)
>>> parser.parse_args(['a'])
Namespace(foo='a')
>>> parser.parse_args([])
Namespace(foo=42)
```
**關鍵字default**也提供一種特殊用法:```default=argparse.SUPPRESS```。在這種情況下,如果命令列並沒有匹配的選項,那麼並不會在**解析結果物件**中新增選項對應的成員,例如:
```python
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', default=argparse.SUPPRESS)
>>> parser.parse_args([])
Namespace()
>>> parser.parse_args(['--foo', '1'])
Namespace(foo='1')
```
### 關鍵字type
預設情況下,**argparse**解析的引數預設為**字串**型別,當然也可以通過**關鍵字type**指定其他任何型別,例如```float```,```int```,甚至是檔案型別```file```, 例如:
```python
>>> 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**指定的是檔案型別,我們還可以通過```FileType('w')以可寫形式開啟檔案,例如:
```python
>>> 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**甚至能指定為函式,經過函式處理後的返回值作為引數值,例如:
```python
>>> 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
當我們需要限制選項的值範圍,我們可以用**關鍵字choices**。**關鍵字choices**限定了引數值的可選列表,如果命令列提供的引數值不在列表中,則會報錯,例如:
```python
>>> 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')
```
當然,需要注意的是,**關鍵字choice**的值必須符合**關鍵字type**指定的型別。
### 關鍵字required
預設情況下,```-f```和```--foo```都是可選的,但如果需要改為**必選**,可以使用**關鍵字required**,例如:
```python
>>> 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
```
### 關鍵字help
**關鍵字help**是選項的說明,在```-h```或者```--help```時會顯示出來,例如:
```python
>>> 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**也支援格式化顯示,```%(prog)s```和大部分**add_argument()**的關鍵字,包括```%(default)s```,```%(type)s```,等等,例如:
```python
>>> 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
```
格式為```%(keyword)s```,如果需要顯示```%```,就需要使用```%%```
還存在一種特殊情況,假設我們不希望引數顯示在*--help*中,我們可以用:**argparse.SUPPRESS**,例如:
```python
>>> 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
```
### 關鍵字dest
**argparse**會把解析的結果儲存成*解析結果物件*的屬性,但是,屬性名是什麼呢?例如,```parser.add_argument(’-f', '--foo')```,解析結果是儲存在屬性```f```中還是```foo```中?**關鍵字dest**就是用於定製屬性名的。
我們先了解預設情況下,屬性名是什麼?
**對位置引數而言,關鍵字dest預設為第一個引數名**,例如:
```python
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
>>> parser.parse_args(['XXX'])
Namespace(bar='XXX')
```
**對可選引數而言,關鍵字dest首選第一個出現的長引數名。如果沒有長引數,則選擇第一個短引數名。不管選擇的是長引數還是短引數,都會把```-|---```給去掉,同時把名字中的```-```符號替換為```_```,以符合python的變數命名規則**,例如:
```python
>>> 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')
```
我們再看看,如果定製屬性名有什麼效果?
```python
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', dest='bar')
>>> parser.parse_args('--foo XXX'.split())
Namespace(bar='XXX')
```
### 關鍵字metavar
在執行```-h|--help```,顯示的幫助資訊中,如何定製選項帶的引數名呢?例如:
```
-t T loop times
```
我希望修改顯示的```T```為```TIMES```,更直觀。這時候我們就可以使用**關鍵字metavar**了。
在預設情況下,對**位置引數**,則會直接顯示引數名,對**可選引數**,則會轉為大寫。例如:
```python
>>> 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
```
上例中,**位置引數bar**直接顯示為*bar*,而**可選引數--foo**帶的引數名就轉大寫顯示*FOO*。
如果我們定製顯示的引數名,該怎麼做呢?
```python
>>> 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
```
當然,還存在一種特殊情況,就是有多個引數```nargs=N```,這時候**關鍵字metavar**可以以列表形式提供啦,例如:
```python
>>> 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
```
最後,有一點要注意的時,**關鍵字metavar**與**關鍵字dest**不一樣的地方在於,**關鍵字metavar僅僅只影響-h|--help的顯示效果,關鍵dest則同時影響解析結果屬性名**
## 獲取解析結果
在[*action='store'*](#store)中提到:**選項名成為了解析結果物件的成員,而選項對應的值則成了成員的值**,所以如果我們需要獲取解析後的結果,直接使用解析結果的成員值就好了。例如:
```python
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', dest='xyz')
>>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
>>> args = parser.parse_args("--foo a b -x c".split())
>>> print(args.foo)
>>> ['a', 'b']
>>> print(args.xyz)
>>> c
```