其他關于Python的總結文章請訪問:http://www.reibang.com/nb/47435944
在Python中處理命令行參數(shù)詳解(sys.argv 與 argparse 詳解)
在運行python程序的時候,往往需要傳入一些參數(shù),本節(jié)主要介紹兩種設置傳入命令行參數(shù)的方法嫂便。
sys.argv
使用sys.argv
處理傳入參數(shù)拗盒,需要引入sys
模塊:
import sys
sys.argv
即是使用命令行運行 python 命令(或者 python3 命令)時獲取到的命令行參數(shù)數(shù)組,它是一個list恰力,包含了python(或者python3)命令后邊傳入的內容叉谜,包括緊跟在 python/python3 后邊的第一個腳本的名稱,后邊其他的參數(shù)踩萎,如果有的話停局,則是按照空格來標識不同的參數(shù),即使用空格隔開的元素(不論是整數(shù)香府、字符串董栽、小數(shù)等)都視為一個獨立的參數(shù),比如如下的程序:
import sys
print(type(sys.argv))
print(len(sys.argv))
print(sys.argv)
我們在命令行中使用如下命令運行該腳本:
python main.py 123 1.5 hello world
就會得到如下的運行結果:
<class 'list'>
5
['main.py', '123', '1.5', 'hello', 'world']
從結果可以看到企孩,這些參數(shù)在sys.argv
中都以字符串的形式存儲锭碳,所以如果想得到整數(shù)、小數(shù)等勿璃,需要使用 int擒抛、float 等進行顯式轉換:
import sys
a = int(sys.argv[1])
b = int(sys.argv[2])
print(a+b)
調用:
main.py 123 456
就會得到579
的結果推汽。
需要注意的是,腳本名稱本身占據了sys.argv[0]
歧沪,所以其他傳入的參數(shù)實際是從sys.argv[1]
開始的歹撒。
這種方式雖然簡單,但是可用性比較小诊胞,必須按照順序傳入參數(shù)暖夭,而且我們熟悉的 -
和 --
形式的參數(shù)是不起作用的:
python main.py --a 123 --b 456
['main.py', '--a', '123', '--b', '456']
所以可以使用下邊的功能更加強大、復雜的第二種方法
argparse
argparse
的使用需要引入argparse
包:
import argparse
我們將這種方法稱為參數(shù)解析器方式撵孤,其使用可以分為三個基本步驟:
實例化參數(shù)解析器
使用ArgumentParser
實例化一個參數(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
:結語早直,會顯示在幫助文檔的后邊 -
argument_default
:全局設置參數(shù)的默認值寥假,默認為None
-
add_help
:為解析器添加一個-h/--help
選項來顯示幫助文檔,默認值為True
添加參數(shù)設置
實例化好一個參數(shù)解析器后就開始為其添加參數(shù)設置霞扬,使用add_argument
方法:正如下邊的這行代碼糕韧,添加了一個 -v
或者 --version
來傳入的參數(shù),它的默認值是 1.0
喻圃,數(shù)據類型是字符串萤彩,并且有幫助信息,幫助信息可以在幫助文檔中顯示斧拍。
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ù)在被解析時使用的名字是指-
或--
后邊的內容,比如這里的v
和version
岗照。 -
type
:命令行參數(shù)應當被轉換成的類型村象,比如bool
、int
攒至、float
厚者、str
等。 -
default
:當參數(shù)未在命令行中出現(xiàn)時迫吐,使用這個默認值库菲。比如:
在命令行調用時如果沒有傳入parser.add_argument("--foo", default='1')
-foo
參數(shù),那這個參數(shù)的值就會被設置為1 -
help
:對于此項參數(shù)的幫助描述渠抹,會被打印到幫助文檔中蝙昙。 -
action
:指定該參數(shù)的動作闪萄,即如何對這個參做哪些處理,可供選擇的動作有很多奇颠,這里列舉一些(完整的以及對于新版的內容可以查看https://docs.python.org/3.9/library/argparse.html#action 以及Action
類的簽名:https://docs.python.org/3.9/library/argparse.html#argparse.Action:-
store
:存儲參數(shù)的值败去,也是默認的動作,即將從命令行獲取的參數(shù)存儲到對應名稱的變量下 -
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ù)值荆几,即默認值分別為 True 和 False
parser.add_argument('--foo', action='store_true')
parser.add_argument('--bar', action='store_false') -
append
:存儲一個list吓妆,對于多次使用一個參數(shù)的時候很有用,會將每次使用這個參數(shù)獲取的值追加的列表中吨铸,比如:
此時如果是這樣調用命令:parser.add_argument('--foo', action='append')
在解析時行拢,名稱python main.py --foo 1 --foo 5.2
foo
對應接收到的值就是一個列表:['1', '5.2']
-
append_const
:和store_const
同理,存儲成const
屬性的列表诞吱,當然也需要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
: 計算一個關鍵字參數(shù)出現(xiàn)的數(shù)目或次數(shù)舟奠,例如這樣設置一個參數(shù):
然后在命令行這樣調用該腳本:parser.add_argument('--foo','-f', action='count')
在解析時,名稱python main.py --foo --foo --foo
foo
(或者f
)對應的值就是3
特別說明房维,對于短格式的名稱沼瘫,可以不使用多個-隔開,這樣也會被計數(shù):
在解析時咙俩,名稱python main.py --foo -ffff
foo
(或者f
)對應的值就是5 -
help
:如果一個參數(shù)被綁定了這個動作伍纫,他的作用就是打印幫助文檔误窖,這跟ArgumentParser
中默認的add_help
是完全相同的 -
version
:綁定這個動作后要使用另一個參數(shù)version
來指定打印的版本堕澄,通常是綁定給--version
或者-v
-
extend
:會將個這個參數(shù)后邊跟的一個或者多個參數(shù)值存儲到列表中瀑志,他和append
是很相似的但是也有不同,使用extend
歌焦,對于一個參數(shù)可以跟多個參數(shù)值飞几,但是使用append
需要多次調用一個參數(shù),每次跟上一個值独撇,比如這樣定義一個參數(shù):
然后這樣調用該腳本:parser.add_argument("--foo", action="extend")
在解析時就會將python main.py --foo f1 f2 f3 f4
foo
參數(shù)解析成一個list:['f1', 'f2', 'f3', 'f4']
-
-
nargs
- 命令行參數(shù)應當消耗的數(shù)目,即指定這個參數(shù)后邊跟的多少個參數(shù)值被吸納到這個參數(shù)以及他的action中躁锁,可以取的值有:- 一個整數(shù):指定個數(shù)纷铣,比如:
表示parser.add_argument('--foo', nargs=2)
-foo
后邊跟的兩個參數(shù)值都是它的 -
'?'
:表示如果有一個就要一個參數(shù),如果沒有就使用default
指定的值战转。 -
'*'
:所有能獲取的參數(shù)搜立,不限個數(shù),包括零個 -
'+'
:和'*'
類似槐秧,都是不限個數(shù)的參數(shù)啄踊,但是至少要有一個參數(shù)忧设,否則會報錯
上述的三個定義可以結合正則表達式來理解,是同樣的道理
- 一個整數(shù):指定個數(shù)纷铣,比如:
-
const
:對于store_const
和append_const
兩個動作颠通,這個參數(shù)是必須要給出的址晕,它指定了調用這兩個動作的時候會將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
設置默認值牢撼,就會默認使用choices
列表中的第一個值做default
值 -
required
:默認值為False
匙隔,如果設置為True
,則表示這個參數(shù)必須傳入熏版,否則會報錯牡直。
解析獲取的參數(shù)
使用ArgumentParser.parse_args
方法解析獲取的參數(shù),返回解析的結果:
args = parser.parse_args()
然后就可以使用設置中對每個參數(shù)指定的名字來獲取它們的值纳决,比如使用args.foo
獲取 --foo
參數(shù)獲得的值
一個完整的簡單的例子
這里有一個簡單的例子碰逸,同時給出了不同的命令行參數(shù)對應的結果
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)
如下是一些調用的例子:
>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