其他關(guān)于Python的總結(jié)文章請訪問:http://m.itdecent.cn/nb/47435944
在Python中處理命令行參數(shù)詳解(sys.argv 與 argparse 詳解)
在運(yùn)行python程序的時候,往往需要傳入一些參數(shù),本節(jié)主要介紹兩種設(shè)置傳入命令行參數(shù)的方法。
sys.argv
使用sys.argv處理傳入?yún)?shù),需要引入sys模塊:
import sys
sys.argv即是使用命令行運(yùn)行 python 命令(或者 python3 命令)時獲取到的命令行參數(shù)數(shù)組,它是一個list,包含了python(或者python3)命令后邊傳入的內(nèi)容,包括緊跟在 python/python3 后邊的第一個腳本的名稱,后邊其他的參數(shù),如果有的話,則是按照空格來標(biāo)識不同的參數(shù),即使用空格隔開的元素(不論是整數(shù)、字符串、小數(shù)等)都視為一個獨(dú)立的參數(shù),比如如下的程序:
import sys
print(type(sys.argv))
print(len(sys.argv))
print(sys.argv)
我們在命令行中使用如下命令運(yùn)行該腳本:
python main.py 123 1.5 hello world
就會得到如下的運(yùn)行結(jié)果:
<class 'list'>
5
['main.py', '123', '1.5', 'hello', 'world']
從結(jié)果可以看到,這些參數(shù)在sys.argv中都以字符串的形式存儲,所以如果想得到整數(shù)、小數(shù)等,需要使用 int、float 等進(jìn)行顯式轉(zhuǎn)換:
import sys
a = int(sys.argv[1])
b = int(sys.argv[2])
print(a+b)
調(diào)用:
main.py 123 456
就會得到579的結(jié)果。
需要注意的是,腳本名稱本身占據(jù)了sys.argv[0],所以其他傳入的參數(shù)實(shí)際是從sys.argv[1]開始的。
這種方式雖然簡單,但是可用性比較小,必須按照順序傳入?yún)?shù),而且我們熟悉的 - 和 -- 形式的參數(shù)是不起作用的:
python main.py --a 123 --b 456
['main.py', '--a', '123', '--b', '456']
所以可以使用下邊的功能更加強(qiáng)大、復(fù)雜的第二種方法
argparse
argparse的使用需要引入argparse包:
import argparse
我們將這種方法稱為參數(shù)解析器方式,其使用可以分為三個基本步驟:
實(shí)例化參數(shù)解析器
使用ArgumentParser實(shí)例化一個參數(shù)解析器:
parser = argparse.ArgumentParser()
其完整的類的簽名如下(可以參考https://docs.python.org/3/library/argparse.html#argumentparser-objects):
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, exit_on_error=True)
這里列舉幾個比較重要、常用的參數(shù):
-
description:一個整體的描述,會顯示在幫助文檔的前邊 -
epilog:結(jié)語,會顯示在幫助文檔的后邊 -
argument_default:全局設(shè)置參數(shù)的默認(rèn)值,默認(rèn)為None -
add_help:為解析器添加一個-h/--help選項(xiàng)來顯示幫助文檔,默認(rèn)值為True
添加參數(shù)設(shè)置
實(shí)例化好一個參數(shù)解析器后就開始為其添加參數(shù)設(shè)置,使用add_argument方法:正如下邊的這行代碼,添加了一個 -v 或者 --version 來傳入的參數(shù),它的默認(rèn)值是 1.0,數(shù)據(jù)類型是字符串,并且有幫助信息,幫助信息可以在幫助文檔中顯示。
parser.add_argument('-v', '--version', default='1.0', type=str, help='print the version of the script')
完整的函數(shù)簽名如下(可以參考https://docs.python.org/3/library/argparse.html#the-add-argument-method):
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
其中一些重要且常用的參數(shù)列在此處:
- names or flags:簡單說就是這個參數(shù)的名字,是必須有的參數(shù),排在第一位(如果有多個名字就排在前幾位),通常會使用“短格式”或/和“長格式”,短格式也就是使用
-后邊加上一個字母的形式,長格式則是--后邊跟上一個單詞的形式,如我們熟知的-v和--version。參數(shù)在被解析時使用的名字是指-或--后邊的內(nèi)容,比如這里的v和version。 -
type:命令行參數(shù)應(yīng)當(dāng)被轉(zhuǎn)換成的類型,比如bool、int、float、str等。 -
default:當(dāng)參數(shù)未在命令行中出現(xiàn)時,使用這個默認(rèn)值。比如:
在命令行調(diào)用時如果沒有傳入parser.add_argument("--foo", default='1')-foo參數(shù),那這個參數(shù)的值就會被設(shè)置為1 -
help:對于此項(xiàng)參數(shù)的幫助描述,會被打印到幫助文檔中。 -
action:指定該參數(shù)的動作,即如何對這個參做哪些處理,可供選擇的動作有很多,這里列舉一些(完整的以及對于新版的內(nèi)容可以查看https://docs.python.org/3.9/library/argparse.html#action 以及Action類的簽名:https://docs.python.org/3.9/library/argparse.html#argparse.Action:-
store:存儲參數(shù)的值,也是默認(rèn)的動作,即將從命令行獲取的參數(shù)存儲到對應(yīng)名稱的變量下 -
store_const:存儲一個const屬性的值,使用這個action時通過const參數(shù)指定參數(shù)值。(后邊會講到const)parser.add_argument('--foo', action='store_const', const=42) -
store_true和 store_false:是 store_const 的特例,不需要使用const指定參數(shù)值,即默認(rèn)值分別為 True 和 False
parser.add_argument('--foo', action='store_true')
parser.add_argument('--bar', action='store_false') -
append:存儲一個list,對于多次使用一個參數(shù)的時候很有用,會將每次使用這個參數(shù)獲取的值追加的列表中,比如:
此時如果是這樣調(diào)用命令:parser.add_argument('--foo', action='append')
在解析時,名稱python main.py --foo 1 --foo 5.2foo對應(yīng)接收到的值就是一個列表:['1', '5.2'] -
append_const:和store_const同理,存儲成const屬性的列表,當(dāng)然也需要const參數(shù)來指定參數(shù)值:parser.add_argument('--str', dest='types', action='append_const', const='hello') parser.add_argument('--int', dest='types', action='append_const', const=20) -
count: 計算一個關(guān)鍵字參數(shù)出現(xiàn)的數(shù)目或次數(shù),例如這樣設(shè)置一個參數(shù):
然后在命令行這樣調(diào)用該腳本:parser.add_argument('--foo','-f', action='count')
在解析時,名稱python main.py --foo --foo --foofoo(或者f)對應(yīng)的值就是3
特別說明,對于短格式的名稱,可以不使用多個-隔開,這樣也會被計數(shù):
在解析時,名稱python main.py --foo -fffffoo(或者f)對應(yīng)的值就是5 -
help:如果一個參數(shù)被綁定了這個動作,他的作用就是打印幫助文檔,這跟ArgumentParser中默認(rèn)的add_help是完全相同的 -
version:綁定這個動作后要使用另一個參數(shù)version來指定打印的版本,通常是綁定給--version或者-v -
extend:會將個這個參數(shù)后邊跟的一個或者多個參數(shù)值存儲到列表中,他和append是很相似的但是也有不同,使用extend,對于一個參數(shù)可以跟多個參數(shù)值,但是使用append需要多次調(diào)用一個參數(shù),每次跟上一個值,比如這樣定義一個參數(shù):
然后這樣調(diào)用該腳本:parser.add_argument("--foo", action="extend")
在解析時就會將python main.py --foo f1 f2 f3 f4foo參數(shù)解析成一個list:['f1', 'f2', 'f3', 'f4']
-
-
nargs- 命令行參數(shù)應(yīng)當(dāng)消耗的數(shù)目,即指定這個參數(shù)后邊跟的多少個參數(shù)值被吸納到這個參數(shù)以及他的action中,可以取的值有:- 一個整數(shù):指定個數(shù),比如:
表示parser.add_argument('--foo', nargs=2)-foo后邊跟的兩個參數(shù)值都是它的 -
'?':表示如果有一個就要一個參數(shù),如果沒有就使用default指定的值。 -
'*':所有能獲取的參數(shù),不限個數(shù),包括零個 -
'+':和'*'類似,都是不限個數(shù)的參數(shù),但是至少要有一個參數(shù),否則會報錯
上述的三個定義可以結(jié)合正則表達(dá)式來理解,是同樣的道理
- 一個整數(shù):指定個數(shù),比如:
-
const:對于store_const和append_const兩個動作,這個參數(shù)是必須要給出的,它指定了調(diào)用這兩個動作的時候會將const所指定的值添加到對象中 -
choices:這個參數(shù)接受一個列表做值,指定所定義的參數(shù)能夠接受的命令行參數(shù)值的范圍,比如:
這表示parser.add_argument("--foo", choices=[1, 2, 3], type=int)-foo這個參數(shù)只能接受1、2、3三個值,如果傳入其他值會報錯,比如:
就會出現(xiàn)錯誤:python main.py --foo 4
值得一提的是,如果在使用usage: main.py [-h] [--foo {1,2,3}] main.py: error: argument --foo: invalid choice: 4 (choose from 1, 2, 3)choices參數(shù)后沒有使用default設(shè)置默認(rèn)值,就會默認(rèn)使用choices列表中的第一個值做default值 -
required:默認(rèn)值為False,如果設(shè)置為True,則表示這個參數(shù)必須傳入,否則會報錯。
解析獲取的參數(shù)
使用ArgumentParser.parse_args方法解析獲取的參數(shù),返回解析的結(jié)果:
args = parser.parse_args()
然后就可以使用設(shè)置中對每個參數(shù)指定的名字來獲取它們的值,比如使用args.foo獲取 --foo 參數(shù)獲得的值
一個完整的簡單的例子
這里有一個簡單的例子,同時給出了不同的命令行參數(shù)對應(yīng)的結(jié)果
import argparse
parser = argparse.ArgumentParser(description='An argparse example')
parser.add_argument("--method", '-m', choices=['add', 'multiple'], help='choose whether to add or to multiply')
parser.add_argument("--A", '-a', default=1, type=int, help="The first number")
parser.add_argument("--B", '-b', default=2, type=int, help="The second number")
args = parser.parse_args()
if args.method == 'add':
print(args.A + args.B)
else:
print(args.A * args.B)
如下是一些調(diào)用的例子:
>python main.py
2
>python main.py --help
usage: main.py [-h] [--method {add,multiple}] [--A A] [--B B]
An argparse example
optional arguments:
-h, --help show this help message and exit
--method {add,multiple}, -m {add,multiple}
choose whether to add or to multiply
--A A, -a A The first number
--B B, -b B The second number
>python main.py --method multiple -a 10 -b 20
200
>python main.py --m add -a 10
12