天天看點

Python argparse 子產品使用詳解

基本用法:

import argparse

def main():
    parser = argparse.ArgumentParser(description="Demo of argparse")
    parser.add_argument('-n','--name', default=' Li ')
    parser.add_argument('-y','--year', default='20')
    args = parser.parse_args()
    print(args)
    name = args.name
    year = args.year
    print('Hello {}  {}'.format(name,year))

if __name__ == '__main__':
    main()

           

其他的幾個案列:

import argparse
parser = argparse.ArgumentParser()
parser.parse_args()
           
parser = argparse.ArgumentParser()
parser.add_argument("echo")
args = parser.parse_args()
print args.echo
           
import argpars
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbosity", help="increase output verbosity")
args = parser.parse_args()
if args.verbosity:
    print "verbosity turned on"
           
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-v", "--verbosity", help="increase output verbosity", action="store_true")
args = parser.parse_args()
print args.verbosity
           

這個子產品主要是解析檔案 和 設定預設參數

下面看下參數的定義:

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 - 某些action和nargs選項要求的常數值。
default - 如果指令行中沒有出現該參數時的預設值。
type - 指令行參數應該被轉換成的類型。
choices - 參數可允許的值的一個容器。
required - 該指令行選項是否可以省略(隻針對可選參數)。
help - 參數的簡短描述。
metavar - 參數在幫助資訊中的名字。
dest - 給parse_args()傳回的對象要添加的屬性名稱。
           

‘store_const’ - 儲存由const關鍵字參數指出的值。(注意const關鍵字參數預設是幾乎沒有幫助的None。)'store_const’動作最常用于指定某種标記的可選參數。例如:

parser.add_argument('--foo', action='store_const', const=42)
           

‘store_true’和’store_false’ - 它們是’store_const’ 的特殊情形,分别用于儲存值True和False。另外,它們分别會建立預設值False 和True。例如:

parser.add_argument('--bar', action='store_false')
 parser.add_argument('--baz', action='store_false')
           

‘append’ - 儲存一個清單,并将每個參數值附加在清單的後面。這對于允許指定多次的選項很有幫助。示例用法:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--foo', action='append')
args = parser.parse_args('--foo 1 --foo 2'.split())
print args.foo
結果:
['1', '2']
在指令行多次輸入--foo 每次輸入一次是算作是一個數組的項
           

‘append_const’ - 儲存一個清單,并将const關鍵字參數指出的值附加在清單的後面。(注意const關鍵字參數預設是None。)‘append_const’ 動作在多個參數需要儲存常量到相同的清單時特别有用。例如:

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--str', dest='types', action='append_const', const=str)
>>> parser.add_argument('--int', dest='types', action='append_const', const=int)
>>> parser.parse_args('--str --int'.split())
Namespace(types=[<type 'str'>, <type 'int'>])
           

‘count’ - 計算關鍵字參數出現的次數。例如,這可用于增加詳細的級别:

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

‘help’ - 列印目前解析器中所有選項的完整的幫助資訊然後退出。預設情況下,help動作會自動添加到解析器中。參見ArgumentParser以得到如何生成輸出資訊

‘version’ - 它期待version=參數出現在add_argument()調用中,在調用時列印出版本資訊并退出:

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

下面讓我來嘗試一把自定義 action 的實作。自定義 action 方法需要繼承自 argparse.Action 類 并且實作一個 call 方法。 call 方法需要定義四個參數變量:

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

代碼:

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

可以直接看到列印的那一行,當我們在執行完 parse_args 的時候,執行到了 print ‘%r %r %r’ % (namespace, values, option_string) 是以列印了出來。

可以看到 namespace 參數是一個 namespace 對象,values 就是給定的值, option_string 如果有可選參數就會加入進這個,如果沒有則為 None。

那麼有人會問, 那 parser 這個參數呢,這個參數經過我的測試就是 .add_argument 之前的那個對象,一模一樣,會被傳遞進去。知道了這些,就可以基于這些知識對 action 這個方法做一些魔改了。這裡就不展開了,根據需求定制即可。

nargs:這個入參可以設定一個 參數後面可以接收幾個值,而且提供了類似于正則的符号來通配一些行為。

ArgumentParser對象通常将一個動作與一個指令行參數關聯。nargs關鍵字參數将一個動作與不同數目的指令行參數關聯在一起。它支援的值有
>>> 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'])
'?'。如果有的話就從指令行讀取一個參數并生成一個元素。如果沒有對應的指令行參數,則産生一個來自default的值。注意,對于可選參數,有另外一種情況 - 有選項字元串但是後面沒有跟随指令行參數。在這種情況下,将生成一個來自const的值。用一些例子加以解釋:

>>>
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='?', const='c', default='d')
>>> parser.add_argument('bar', nargs='?', default='d')
>>> parser.parse_args('XX --foo YY'.split())
Namespace(bar='XX', foo='YY')
>>> parser.parse_args('XX --foo'.split())
Namespace(bar='XX', foo='c')
>>> parser.parse_args(''.split())
Namespace(bar='d', foo='d')
nargs='?'的一種更常見的用法是允許可選的輸入和輸出檔案:

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

>>>
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', nargs='*')
>>> parser.add_argument('--bar', nargs='*')
>>> parser.add_argument('baz', nargs='*')
>>> parser.parse_args('a b --foo x y --bar 1 2'.split())
Namespace(bar=['1', '2'], baz=['a', 'b'], foo=['x', 'y'])
'+'。和'*'一樣,出現的所有指令行參數都被收集到一個清單中。除此之外,如果沒有至少出現一個指令行參數将會産生一個錯誤資訊。例如:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('foo', nargs='+')
>>> parser.parse_args('a b'.split())
Namespace(foo=['a', 'b'])
>>> parser.parse_args(''.split())
usage: PROG [-h] foo [foo ...]
PROG: error: too few arguments
argparse.REMAINDER.所有剩餘的指令行參數都被收集到一個清單中。這通常用于指令行工具分發指令到其它指令行工具:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo')
>>> parser.add_argument('command')
>>> parser.add_argument('args', nargs=argparse.REMAINDER)
>>> print parser.parse_args('--foo B cmd --arg1 XX ZZ'.split())
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
           

const: const 參數在某些特定的 action 上面已經介紹到了會被使用,還有就是 nargs 是 ‘?’ 的時候會優先使用 const 裡面的值。

default: 對于參數,default的值用于選項字元串沒有出現在指令行中的時候。

type: 可以設定傳入參數要求的類型。

choices: 可以設定填入的參數在 choices 指定的範圍内。

require: 有此參數,如果傳入的時候沒有将報出一個錯誤

help: 填寫該參數背後的一些幫助資訊。

metavar 和 dst

當ArgumentParser生成幫助資訊時,它需要以某種方式引用每一個參數。 預設情況下,ArgumentParser對象使用dest的值作為每個對象的“名字”。預設情況下,對于位置參數直接使用dest的值,對于可選參數則将dest的值變為大寫。是以,位置參數dest='bar'将引用成bar。後面帶有一個指令行參數的可選參數--foo将引用成FOO。一個例子:

>>>
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> parser.add_argument('bar')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage:  [-h] [--foo FOO] bar

positional arguments:
 bar

optional arguments:
 -h, --help  show this help message and exit
 --foo FOO
可以用metavar指定另外一個名字:

>>>
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo', metavar='YYY')
>>> parser.add_argument('bar', metavar='XXX')
>>> parser.parse_args('X --foo Y'.split())
Namespace(bar='X', foo='Y')
>>> parser.print_help()
usage:  [-h] [--foo YYY] XXX

positional arguments:
 XXX

optional arguments:
 -h, --help  show this help message and exit
 --foo YYY
注意metavar隻會改變顯示出來的名字 - parse_args() 對象中屬性的名字仍然由dest的值決定。

nargs的不同值可能導緻metavar使用多次。傳遞一個清單給metavar将給每個參數指定一個不同的顯示名字:

>>>
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('-x', nargs=2)
>>> parser.add_argument('--foo', nargs=2, metavar=('bar', 'baz'))
>>> parser.print_help()
usage: PROG [-h] [-x X X] [--foo bar baz]

optional arguments:
 -h, --help     show this help message and exit
 -x X X
 --foo bar baz
大部分ArgumentParser動作給parse_args()傳回對象的某個屬性添加某些值。該屬性的名字由add_argument()的dest關鍵字參數決定。對于位置參數的動作,dest 通常作為第一個參數提供給add_argument():

>>>
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('bar')
>>> parser.parse_args('XXX'.split())
Namespace(bar='XXX')
對于可選參數的動作,dest的動作通常從選項字元串推導出來。ArgumentParser生成的dest的值是将第一長的選項字元串前面的--字元串去掉。如果沒有提供長選項字元串,dest的獲得則是将第一個短選項字元串前面的-字元去掉。任何内部的-将被轉換為_字元以確定字元串是合法的屬性名字。下面的執行個體解釋了這個行為:

>>>
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-f', '--foo-bar', '--foo')
>>> parser.add_argument('-x', '-y')
>>> parser.parse_args('-f 1 -x 2'.split())
Namespace(foo_bar='1', x='2')
>>> parser.parse_args('--foo 1 -y 2'.split())
Namespace(foo_bar='1', x='2')
dest允許提供自定義的屬性名:

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