1. 程式人生 > >argparse - 命令列選項與引數解析

argparse - 命令列選項與引數解析

閱讀原文點我

argparse模組作為optparse的一個替代被新增到Python2.7。argparse的實現支援一些不易於新增到optparse以及要求向後不相容API變化的特性,因此以一個新模組新增到標準庫。

與optparse相比較

argparse的API類似於optparse,甚至在很多情況下通過更新所使用的類名和方法名,使用argparse作為一個簡單的替代。然而,有些地方在新增新特性時不能保持直接相容性。

你必須視情況決定是否升級已有的程式。如果你已編寫了額外的程式碼以彌補optparse的侷限,也許你想升級程式以減少你需要維護的程式碼量。若argparse在所有部署平臺上都可用,那麼新的程式應儘可能使用argparse。

設定一個解析器

使用argparse的第一步就是建立一個解析器物件,並告訴它將會有些什麼引數。那麼當你的程式執行時,該解析器就可以用於處理命令列引數。

解析器類是 ArgumentParser 。構造方法接收幾個引數來設定用於程式幫助文字的描述資訊以及其他全域性的行為或設定。

import argparse
parser = argparse.ArgumentParser(description='This is a PyMOTW sample program')

定義引數

argparse是一個全面的引數處理庫。引數可以觸發不同的動作,動作由 add_argument()

 方法的 action 引數指定。 支援的動作包括儲存引數(逐個地,或者作為列表的一部分),當解析到某引數時儲存一個常量值(包括對布林開關真/假值的特殊處理),統計某個引數出現的次數,以及呼叫一個回撥函式。

預設的動作是儲存引數值。在這種情況下,如果提供一個型別,那麼在儲存之前會先把該引數值轉換成該型別。如果提供 dest 引數,引數值就儲存為命令列引數解析時返回的名稱空間物件中名為該 dest 引數值的一個屬性。

解析一個命令列

定義了所有引數之後,你就可以給 parse_args() 傳遞一組引數字串來解析命令列。預設情況下,引數是從 sys.argv[1:]

 中獲取,但你也可以傳遞自己的引數列表。選項是使用GNU/POSIX語法來處理的,所以在序列中選項和引數值可以混合。

parse_args() 的返回值是一個名稱空間,包含傳遞給命令的引數。該物件將引數儲存其屬性,因此如果你的引數 dest 是 "myoption",那麼你就可以args.myoption 來訪問該值。

簡單示例

以下簡單示例帶有3個不同的選項:一個布林選項(-a),一個簡單的字串選項(-b),以及一個整數選項(-c)。

import argparse

parser = argparse.ArgumentParser(description='Short sample app')

parser.add_argument('-a', action="store_true", default=False)
parser.add_argument('-b', action="store", dest="b")
parser.add_argument('-c', action="store", dest="c", type=int)

print parser.parse_args(['-a', '-bval', '-c', '3'])

有幾種方式傳遞值給單字元選項。以上例子使用了兩種不同的形式,-bval-c val

$ python argparse_short.py
Namespace(a=True, b='val', c=3)

在輸出中與'c'關聯的值是一個整數,因為程式告訴ArgumentParser在儲存之前先轉換該引數。

“長”選項名字,即選項的名字多於一個字元,以相同的方式進行處理。

import argparse

parser = argparse.ArgumentParser(description='Example with long option names')

parser.add_argument('--noarg', action="store_true", default=False)
parser.add_argument('--witharg', action="store", dest="witharg")
parser.add_argument('--witharg2', action="store", dest="witharg2", type=int)

print parser.parse_args(['--noarg', '--witharg', 'val', '--withargs=3'])

結果也類似:

$ python argparse_long.py
Namespace(noarg=True, witharg='val', witharg2=3)

argparse區別於optparse的一個地方是對非選項引數值的處理。optparse只進行選項解析,而argparse是一個全面的命令列引數解析工具,也處理非選項引數。

import argparse

parser = argparse.ArgumentParser(description='Example with non-optional arguments')

parser.add_argument('count', action="store", type=int)
parser.add_argument('units', action="store")

print parser.parse_args()

在這個例子中,“count”引數是一個整數,“units”引數儲存為一個字串。其中任意一個引數若沒有在命令列中提供,或給定的值不能被轉換為正確的型別,就會報告一個錯誤。

$ python argparse_arguments.py 3 inches

Namespace(count=3, units='inches')

$ python argparse_arguments.py some inches

usage: argparse_arguments.py [-h] count units
argparse_arguments.py: error: argument count: invalid int value: 'some'

$ python argparse_arguments.py

usage: argparse_arguments.py [-h] count units
argparse_arguments.py: error: too few arguments

引數動作

argparse內建6種動作可以在解析到一個引數時進行觸發:

store 儲存引數值,可能會先將引數值轉換成另一個數據型別。若沒有顯式指定動作,則預設為該動作。

store_const 儲存一個被定義為引數規格一部分的值,而不是一個來自引數解析而來的值。這通常用於實現非布林值的命令列標記。

store_ture/store_false 儲存相應的布林值。這兩個動作被用於實現布林開關。

append 將值儲存到一個列表中。若引數重複出現,則儲存多個值。

append_const 將一個定義在引數規格中的值儲存到一個列表中。

version 列印關於程式的版本資訊,然後退出

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('-s', action='store', dest='simple_value',
        help='Store a simple value')

parser.add_argument('-c', action='store_const', dest='constant_value',
        const='value-to-store',
        help='Store a constant value')

parser.add_argument('-t', action='store_true', default=False,
        dest='boolean_switch',
        help='Set a switch to true')
parser.add_argument('-f', action='store_false', default=False,
        dest='boolean_switch',
        help='Set a switch to false')

parser.add_argument('-a', action='append', dest='collection',
        default=[],
        help='Add repeated values to a list')

parser.add_argument('-A', action='append_const', dest='const_collection',
        const='value-1-to-append',
        default=[],
        help='Add different values to list')
parser.add_argument('-B', action='append_const', dest='const_collection',
        const='value-2-to-append',
        help='Add different values to list')

parser.add_argument('--version', action='version', version='%(prog)s 1.0')

results = parser.parse_args()
print 'simple_value     =', results.simple_value
print 'constant_value   =', results.constant_value
print 'boolean_switch   =', results.boolean_switch
print 'collection       =', results.collection
print 'const_collection =', results.const_collection

$ python argparse_action.py -h

usage: argparse_action.py [-h] [-s SIMPLE_VALUE] [-c] [-t] [-f]
                          [-a COLLECTION] [-A] [-B] [--version]

optional arguments:
  -h, --help       show this help message and exit
  -s SIMPLE_VALUE  Store a simple value
  -c               Store a constant value
  -t               Set a switch to true
  -f               Set a switch to false
  -a COLLECTION    Add repeated values to a list
  -A               Add different values to list
  -B               Add different values to list
  --version        show program's version number and exit

$ python argparse_action.py -s value

simple_value     = value
constant_value   = None
boolean_switch   = False
collection       = []
const_collection = []

$ python argparse_action.py -c

simple_value     = None
constant_value   = value-to-store
boolean_switch   = False
collection       = []
const_collection = []

$ python argparse_action.py -t

simple_value     = None
constant_value   = None
boolean_switch   = True
collection       = []
const_collection = []

$ python argparse_action.py -f

simple_value     = None
constant_value   = None
boolean_switch   = False
collection       = []
const_collection = []

$ python argparse_action.py -a one -a two -a three

simple_value     = None
constant_value   = None
boolean_switch   = False
collection       = ['one', 'two', 'three']
const_collection = []

$ python argparse_action.py -B -A

simple_value     = None
constant_value   = None
boolean_switch   = False
collection       = []
const_collection = ['value-2-to-append', 'value-1-to-append']

$ python argparse_action.py --version

argparse_action.py 1.0

選項字首

argparse選項的預設語法是基於Unix約定的,使用一個“-”字首來表示命令列開關。argparse支援其他字首,因此你可以使得你的程式遵照本地平臺的預設語法(例如,在Window上使用“/”)或者遵循不同的約定。

import argparse

parser = argparse.ArgumentParser(description='Change the option prefix charaters', 
        prefix_chars='-+/')

parser.add_argument('-a', action="store_false", default=None,
        help='Turn A off')

parser.add_argument('+a', action="store_true", default=None,
        help='Turn A on')

parser.add_argument('//noarg', '++noarg', action="store_true", default=False)

print parser.parse_args()

ArgumentParser 方法的prefix_chars 引數設定為一個字串,該字串包含所有允許用來表示選項的字元。需要理解的是雖然prefix_chars包含允許用於開關的字元,但單個引數定義只能使用一種給定的開關語法。這讓你可以對使用不同字首的選項是否是別名(比如獨立於平臺的命令列語法的情況)或替代選擇(例如,使用“+”表明開啟一個開發,“-”則為關閉一個開關)進行顯式地控制。在上述例子中,+a-a是不同的引數,//noarg 也可以 ++noarg 提供,但不是 --noarg

$ python argparse_prefix_chars.py -h

usage: argparse_prefix_chars.py [-h] [-a] [+a] [//noarg]

Change the option prefix characters

optional arguments
    -h, --help  show this help message and exit
    -a  Turn A off
    +a  Turn A on
    //noarg,++noarg

$ python argparse_prefix_chars.py +a

Namespace(a=True, noarg=False)

$ python argparse_prefix_chars.py -a

Namespace(a=False, noarg=False)

$ python argparse_prefix_chars.py //noarg

Namespace(a=None, noarg=True)

$ python argparse_prefix_chars.py ++noarg

Namespace(a=None, noarg=True)

$ python argparse_prefix_chars.py --noarg

usage: argparse_prefix_chars.py [-h] [-a] [+a] [//noarg]
argparse_prefix_chars.py: error: unrecognized arguments: --noarg

 

 

湊字數