在Python中處理命令行參數(shù)詳解(sys.argv 與 argparse 詳解)

其他關(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)容,比如這里的 vversion
  • type:命令行參數(shù)應(yīng)當(dāng)被轉(zhuǎn)換成的類型,比如bool、int、floatstr等。
  • default:當(dāng)參數(shù)未在命令行中出現(xiàn)時,使用這個默認(rèn)值。比如:
    parser.add_argument("--foo", default='1')
    
    在命令行調(diào)用時如果沒有傳入 -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ù)獲取的值追加的列表中,比如:
      parser.add_argument('--foo', action='append')
      
      此時如果是這樣調(diào)用命令:
      python main.py --foo 1 --foo 5.2
      
      在解析時,名稱 foo 對應(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ù):
      parser.add_argument('--foo','-f', action='count')
      
      然后在命令行這樣調(diào)用該腳本:
      python main.py --foo --foo --foo
      
      在解析時,名稱 foo (或者f)對應(yīng)的值就是3
      特別說明,對于短格式的名稱,可以不使用多個-隔開,這樣也會被計數(shù):
      python main.py --foo -ffff
      
      在解析時,名稱 foo(或者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ù):
      parser.add_argument("--foo", action="extend")
      
      然后這樣調(diào)用該腳本:
      python main.py --foo f1 f2 f3 f4
      
      在解析時就會將foo參數(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á)式來理解,是同樣的道理
  • const:對于 store_constappend_const 兩個動作,這個參數(shù)是必須要給出的,它指定了調(diào)用這兩個動作的時候會將const所指定的值添加到對象中
  • choices:這個參數(shù)接受一個列表做值,指定所定義的參數(shù)能夠接受的命令行參數(shù)值的范圍,比如:
    parser.add_argument("--foo", choices=[1, 2, 3], type=int)
    
    這表示-foo這個參數(shù)只能接受1、2、3三個值,如果傳入其他值會報錯,比如:
    python main.py --foo 4
    
    就會出現(xiàn)錯誤:
    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
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容