Python argparse標準庫快速入門

Python是一門很是好用的腳本語言,天然使用它來開發命令行程序也比較方便。並且Python的標準庫中有一個名爲argparse的庫,能夠很是方便的讓咱們把命令行參數轉換成所需的數據格式。下面就讓咱們來看看如何使用argparse標準庫吧。html

若是想詳細瞭解argparse的話,能夠查看Python官方文檔,目前已經出了中文版文檔,極大的方便了咱們中國開發者,雖然有些地方沒有完整翻譯,可是已經徹底夠用了。python

初見argparse

首先來看看argparse的基本用法,下面是最簡單的一個例子。能夠看到argparse標準庫其實用起來很簡單,分紅三個步驟:正則表達式

  1. 建立ArgumentParser對象
  2. 使用add_argument方法添加參數
  3. 使用parse_args方法接受並解析對象

下面咱們就依次來看看這些步驟吧。數組

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-from', type=str)
parser.add_argument('-to', type=str, default='everyone')

args = parser.parse_args('-from yitian'.split(' '))
print(args)

# 運行結果
# Namespace(from='yitian', to='everyone')

ArgumentParser

ArgumentParser是最重要的一個類,咱們要使用argparse標準庫就必然須要建立這個類的實例。若是有須要的話,能夠經過在構造函數中設置各類參數的方式來修改ArgumentParser類的行爲。因爲參數項比較多,因此官方文檔建議咱們使用關鍵字參數的方式來添加參數。app

  • prog - 程序的名稱(默認:sys.argv[0]),默認是Python程序的文件名
  • usage - 描述程序用途的字符串(默認值:從添加到解析器的參數生成)
  • description - 在參數幫助文檔以前顯示的文本(默認值:無)
  • epilog - 在參數幫助文檔以後顯示的文本(默認值:無)
  • parents - 一個 ArgumentParser 對象的列表,它們的參數也應包含在內。假如多個parser有一些能夠共享的參數,能夠經過設置子parser的方式來共享
  • formatter_class - 用於自定義幫助文檔輸出格式的類
  • prefix_chars - 可選參數的前綴字符集合(默認值:'-')
  • fromfile_prefix_chars - 當須要從文件中讀取其餘參數時,用於標識文件名的前綴字符集合(默認值:None
  • argument_default - 參數的全局默認值(默認值: None),假如須要給全部參數指定一個相通的默認值,能夠修改這個,若是但願全局禁用默認值,可使用argparse.SUPRESS
  • conflict_handler - 解決衝突選項的策略(一般是沒必要要的)
  • add_help - 爲解析器添加一個 -h/--help 選項(默認值: True
  • allow_abbrev - 若是縮寫是無歧義的,則容許縮寫長選項 (默認值:True

add_argument方法

有了Parser實例,就能夠調用它的add_argument方法來添加程序能夠接受的參數了。這個參數比較複雜,功能也十分強大。函數

  • name or flags - 一個命名或者一個選項字符串的列表,例如 foo 或 -f, --foo
  • action - 當參數在命令行中出現時使用的動做基本類型。
  • nargs - 命令行參數應當消耗的數目。
  • const - 被一些 action 和 nargs 選擇所需求的常數。
  • default - 當參數未在命令行中出現時使用的值。
  • type - 命令行參數應當被轉換成的類型。
  • choices - 可用的參數的容器。
  • required - 此命令行選項是否可省略 (僅選項可用)。
  • help - 一個此選項做用的簡單描述。
  • metavar - 在使用方法消息中使用的參數值示例。
  • dest - 被添加到 parse_args() 所返回對象上的屬性名。

參數名

方法的第一個參數是參數名稱,能夠是一個字符串(name)或者是-開頭的一組字符串(flags),前者是位置參數,會按照添加的順序被讀取;後者是關鍵字參數,能夠以任意順序指定。若是指定的是關鍵字參數(flags),能夠同時添加縮寫和完整名,它們分別須要用---來作前綴。學習

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('foo')
parser.add_argument('bar')
parser.add_argument('-f', '--ff', action='store_true')

args = parser.parse_args('FOO BAR -f'.split(' '))
print(args)
args = parser.parse_args('--ff BAR FOO'.split(' '))
print(args)

'''運行結果,注意指定的參數和獲取到的結果的不一樣
Namespace(bar='BAR', ff=True, foo='FOO')
Namespace(bar='FOO', ff=True, foo='BAR')
'''

action(行爲)

接下來介紹的參數都是關鍵字參數,能夠按需制定。這裏比較重要的一個是action,它指定了讀取參數接下來要作什麼。這部分能夠看官方文檔,介紹的比較全面,並且有對應的例子。我這裏只簡單介紹一下。測試

  • store和store_const用來保存具體的值,他們之間有一些區別,一會再介紹。
  • store_true和store_false比較方便,能夠用來設置一些開關參數。例如我想指定-f的時候開啓某個功能,忽略這個參數的時候不執行,就能夠把它的行爲指定成store_true,而後在程序中就能夠獲得f名字的參數真值,而後簡單的條件判斷就能夠了。
  • append和append_const會將參數存儲成一個列表。
  • count會存儲參數出現的次數。常見用法是指定日誌輸出級別,例若有的程序-v會顯示簡單輸出,-vv會顯示覆雜輸出。

甚至若是需求更復雜的話,還能夠本身實現一個新的Action類,而後添加給add_argument方法。ui

nargs(參數數目)

這個參數指定你的程序能夠接受的參數個數,可使用如下幾個值:this

  • N(一個正整數),表示後面的N個值會被讀取爲參數,注意指定爲1的話會變成一個單元素列表。
  • ?,和正則表達式裏的概念差很少,後面的一個值會被讀取,若是沒有的話會從default讀入。
  • +,後面的多個值會被讀取,若是沒有會拋出異常。
  • ?,後面的多個值會被讀取,沒有值的話也能夠。
  • argparse.REMAINDER,它會將後面全部值讀取爲一個參數,一般用做向其餘命令行傳遞參數用。

默認狀況下nargs會按照action的類型來判斷參數個數,store和store_const會讀取後面的一個值做爲參數。

const

這個參數須要和帶有const的action來配合使用。

default

指定參數的默認值。這裏有一個頗有趣的點,若是你看官方文檔比較仔細的話,可能會產生一個和我同樣的疑問:store_const和const配合使用能夠指定默認值,而store和default也能夠指定默認值,那麼它們之間有什麼區別呢?其實區別仍是蠻大的,看看下面這個例子就明白了。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-foo', action='store', nargs='?', default=10, const=20)

print(parser.parse_args('-foo 0'.split(' ')))
print(parser.parse_args('-foo'.split(' ')))
print(parser.parse_args(''))

'''
Namespace(foo='0')
Namespace(foo=20)
Namespace(foo=10)
'''
  1. 當foo參數徹底忽略的時候,會使用default的值。
  2. 當指定了foo參數,但沒有指定後面的值時,會使用const的值。
  3. 當指定了foo參數和後面的值時,會使用咱們指定的值。

type

這個是指定參數類型的,int、float、str那些。固然比較特殊的一個是open,它會將參數做爲文件來打開。

若是默認的open還不能知足,還可使用argparse.FileType,它提供了讀寫模式、文件編碼、緩衝區大小等詳細設置。

parser.add_argument('bar', type=argparse.FileType('w'))

甚至有需求的話,這裏還可使用咱們本身的函數,只要它的參數是一個字符串,返回值是轉換之後的值就能夠。

choices

若是確認參數範圍限定是幾個定值,可使用choices參數來指定,可接受的值包括字面值列表以及range函數。

required

指定參數是不是必須的。

metavar和dest

metavar參數用來指定參數的顯示名稱,而dest用來指定參數底層使用的屬性名。

注意下面的程序輸出,foo參數只修改了metavar,因此在幫助信息輸出中發生了變化,可是在Namespace底層仍然使用foo保存值。而bar參數修改了dest,因此底層屬性名發生了變化,可是在幫助信息中並無什麼改變。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-foo', metavar='foooo')
parser.add_argument('-bar', dest='barrrr')

parser.print_help()
print(parser.parse_args(''))

'''
usage: argparse_sample.py [-h] [-foo foooo] [-bar bar]

optional arguments:
  -h, --help  show this help message and exit
  -foo foooo
  -bar bar
Namespace(barrrr=None, foo=None)
'''

help

有條件的話最好給每一個參數添加幫助信息,這樣使用者在用-h命令的時候就能夠看到參數的幫助信息了。

parse_args方法

編輯好了參數,就能夠調用parse_args方法來處理參數了,它會返回一個命名空間對象,包含了解析以後的參數。若是要測試方法的話,能夠手動給它傳遞一組參數,不然的話,它會自動從命令行參數讀取。另外它還支持幾個比較有用的特性:

  • 若是參數比較長,可使用等號來鏈接參數與值,例如-foo=bar
  • 若是參數是單字母長度的,能夠將參數和值直接寫在一塊兒。
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-foo')
parser.add_argument('-b')

print(parser.parse_args('-foo=bar'.split()))
print(parser.parse_args('-bX'.split()))

'''
Namespace(b=None, foo='bar')
Namespace(b='X', foo=None)
'''

另外還支持默認無歧義的參數縮寫。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-f1aaaaaaaaaa')
parser.add_argument('-f2aaaaaaaaaa')

print(parser.parse_args('-f1 a -f2 b'.split(' ')))

命名空間對象

前面也看到了,解析完參數返回的值是命名空間對象,它用起來很是簡單,直接訪問屬性值就能夠了。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-a')
parser.add_argument('-b')

args = parser.parse_args('-a a -b b'.split(' '))
print(args.a)

# a

其餘特性

argparse還支持一些其餘特性,這裏就很少作介紹了,詳情請直接參考官方文檔。

  • 子parser。有些程序支持子命令,這時候可使用子parser建立更復雜的parser。
  • FileType。更詳細的設置文件參數的方法。
  • 參數組。若是參數比較多,可使用參數組的方式將功能相近的參數進行分組,這樣不論是開發人員仍是使用人員都能更清晰的使用參數。
  • 互斥參數組。若是某些參數不能同時使用,能夠將它們加到互斥參數組中。
  • 部分解析。默認狀況下parse_argument在遇到未知參數的時候會報錯,若是須要保存這些參數傳遞給其餘命令行的時候,可使用parse_known_args方法。它不會由於未知參數報錯, 並且會將全部不認識的參數存儲成一個列表做爲第二個返回值。

簡單實例

扯了大半天,你們可能仍是有點不會用argparse,不過其實只要看一個簡單的例子就能夠了。保存下面的文件,而後用命令行調用,看看不一樣的參數會有什麼輸出。

import argparse

parser = argparse.ArgumentParser(prog='ParserSample',
                                 description='簡單實例程序,學習如何解析命令行參數',
                                 epilog='很簡單就能夠學會')

parser.add_argument('greeting', type=str, help='問候信息,必需')
parser.add_argument('-fromm', default='yitian', type=str, help='發送人,默認是易天')
parser.add_argument('-to', default='everyone', type=str, nargs='*', help='接收人,默認是全部人')
parser.add_argument('-p', action='store_true', help='是否添加感嘆號')

args = parser.parse_args()

output = f'{args.fromm} say {args.greeting} to {args.to}'
if args.p:
    output = output + '!'

print(output)

'''
usage: ParserSample [-h] [-fromm FROMM] [-to [TO [TO ...]]] [-p] greeting

簡單實例程序,學習如何解析命令行參數

positional arguments:
  greeting           問候信息,必需

optional arguments:
  -h, --help         show this help message and exit
  -fromm FROMM       發送人,默認是易天
  -to [TO [TO ...]]  接收人,默認是全部人
  -p                 是否添加感嘆號

很簡單就能夠學會
'''
相關文章
相關標籤/搜索