Python 命令列引數詳解
- 0. 命令列引數
- 1. sys.argv
- 2. getopt
- 2.1 getopt.getopt 方法
- 2.2 Exception getopt.GetoptError
- 3. argparse
0. 命令列引數
通常,對于大型專案程式而言,執行程式的一個必要的步驟是正確處理命令列引數,這些命令列引數是提供給包含某種引數化資訊的程式或腳本的引數,例如,在計算機視覺專案中,影像和不同型別的檔案通常作為命令列引數傳遞給腳本,用于使程式可以處理不同圖片或者不同型別檔案,
命令列引數是引數化程式執行的一種常見且簡單的方法,下面主要介紹三種常見的獲取和決議命令列引數的方法,
1. sys.argv
為了處理命令列引數,Python 中內置了 sys.argv 模塊,通過模塊中的 sys.argv 就可以訪問到所有的命令列引數,它的回傳值是包含所有命令列引數的串列 (list),當程式執行時,Python 從命令列獲取所有值并將它們存盤在 sys.argv 串列中,串列的第一個元素 sys.argv[0] 是腳本的完整路徑(或腳本名稱——取決于具體作業系統),串列的第二個元素是腳本的第一個命令列引數,即 sys.argv[1],依此類推,這可以通過下圖中清晰的看出,其中 script_1.py 腳本使用兩個引數執行:

接下來,讓我們看看 sys.argv 是如何作業的,首先撰寫 scripy_1.py 腳本:
import sys
print("正在運行的腳本名稱: '{}'".format(sys.argv[0]))
print("腳本的引數數量: '{}'".format(len(sys.argv)))
print("腳本的引數: '{}'".format(str(sys.argv)))
如果我們不使用任何引數執行這個腳本:
python script_1.py
將會看到如下資訊:
正在運行的腳本名稱: 'script_1.py'
腳本的引數數量: '1'
腳本的引數: '['script_1.py']'
如果我們使用多個引數執行此腳本:
python script_1.py OpenCV -i test.png
將得到以下資訊:
正在運行的腳本名稱: 'script_1.py'
腳本的引數數量: '4'
腳本的引數: '['script_1.py', 'OpenCV', '-i', 'test.png']'
如上所示,串列的第一個元素 script_1.py (sys.argv[0]) 是腳本名稱,串列的第二個元素 (sys.argv[1]) OpenCV 是腳本的第一個引數,但同時也可以看到,sys.argv 將命令列選項 -i 也識別為引數,這樣并不能方便的滿足我們的需求,因此引入 getopt 模塊來識別命令列選項,
2. getopt
getopt 模塊是專門處理命令列引數的模塊,用于獲取命令列選項和引數,命令列選項使得程式的引數更加靈活,其支持短選項模式(-)和長選項模式(–),
該模塊提供了兩個方法及一個例外處理來決議命令列引數,
2.1 getopt.getopt 方法
getopt.getopt 方法用于決議命令列引數串列,其語法格式如下:
getopt.getopt(args, options[, long_options])
方法引數說明如下表所示:
| 引數 | 說明 |
|---|---|
| args | 要決議的命令列引數串列,一般是sys.argv[1:],需要過濾掉腳本名(sys.argv[0]) |
| options | 以字串的格式定義,options 后的冒號 “:” 表示如果設定該選項,必須有附加的引數,否則就不附加引數 |
| long_options | 以串列的格式定義,long_options 后的等號 “=” 表示該選項必須有附加的引數,不帶冒號表示該選項不附加引數 |
該方法回傳值由兩個元素組成: 第一個是 (option, value) 元組的串列, 第二個是引數串列,包含那些沒有 - 或 – 的引數,
下面撰寫 script_2.py 腳本進行演示:
import sys
import getopt
def main(argv):
input_file = ""
output_file = ""
# "hi:o:": 短格式分析串, h 后面沒有冒號, 表示后面不帶引數; i 和 o 后面帶有冒號, 表示后面帶引數
# ["help", "input_file=", "output_file="]: 長格式分析串串列, help后面沒有等號, 表示后面不帶引數; input_file和output_file后面帶冒號, 表示后面帶引數
# 回傳值包括 `opts` 和 `args`, opts 是以元組為元素的串列, 每個元組的形式為: (選項, 附加引數),如: ('-i', 'test.png');
# args是個串列,其中的元素是那些不含'-'或'--'的引數
opts, args = getopt.getopt(argv[1:], "hi:o:", ["help", "input_file=", "output_file="])
for opt, arg in opts:
if opt in ("-h", "--help"):
print('script_2.py -i <input_file> -o <output_file>')
print('or: test_arg.py --input_file=<input_file> --output_file=<output_file>')
sys.exit()
elif opt in ("-i", "--input_file"):
input_file = arg
elif opt in ("-o", "--output_file"):
output_file = arg
print('輸入檔案為:', input_file)
print('輸出檔案為:', output_file)
# 列印不含'-'或'--'的引數
for i in range(0, len(args)):
print('不含'-'或'--'的引數 %s 為:%s' % (i + 1, args[i]))
if __name__ == "__main__":
main(sys.argv)
使用帶有命令列選項的命令執行此腳本,以下兩種方式是等價的:
# 方式1
python scripy_1.py -i test.png -o output.png OpenCV
# 方式2
python scripy_1.py --input_file test.png --output_file output.png OpenCV
輸出得到以下資訊:
輸入檔案為: test.png
輸出檔案為: output.png
不含'-'或'--'的引數 1 為:OpenCV
2.2 Exception getopt.GetoptError
在引數串列中沒有找到所傳遞引數,或選項的需要的引數為空時會觸發該例外,例外的引數是一個字串,表示錯誤的原因,屬性 msg 和 opt 為相關選項的錯誤資訊,
在上述代碼中添加例外處理,檢查此錯誤資訊:
# ...
def main(argv):
input_file = ""
output_file = ""
try:
opts, args = getopt.getopt(argv[1:], "hi:o", ["help", "input_file=", "output_file="])
except getopt.GetoptError as e:
print(e.msg)
print(e.opt)
sys.exit(2)
# ...
使用錯誤的格式選項傳遞引數執行腳本:
python scripy_1.py -f
輸出以下錯誤資訊:
option -f not recognized
f
3. argparse
當程式中使用采用復雜引數或多個檔案名時,推薦使用 Python 的 argparse 庫,它以系統的方式處理命令列引數,從而可以撰寫用戶友好的命令列程式,Python 標準庫 argparse 同樣也是用于決議命令列引數的模塊,首先,由程式確定所需的引數,然后, argparse 將這些引數決議為 sys.argv,此外,argparse 會生成幫助和使用資訊提示,并在提供無效引數時發出錯誤,
為了介紹此模塊,撰寫 script_3.py,如下所示:
import argparse
parser = argparse.ArgumentParser()
parser.parse_args()
不帶引數運行此腳本不會向 stdout 顯示任何內容,但是,如果使用 --help 或 -h 選項,將得到腳本的使用資訊提示:
usage: scripy_3.py [-h]
optional arguments:
-h, --help show this help message and exit
指定其他引數會導致錯誤,例如使用如下命令:
scripy_3.py -i
則會報導致錯誤:
usage: scripy_3.py [-h]
argparse_minimal.py: error: unrecognized arguments: -i
由于未定義引數,因此不允許其他引數,接下來就添加一個引數,撰寫 script_4.py 腳本:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("first_argument", help="this is the string text in connection with first_argument")
args = parser.parse_args()
print(args.first_argument)
這里添加了 add_argument() 方法,此方法用于指定程式將接受哪些命令列選項,此處添加了 first_argument 引數,此外, argparse 模塊存盤所有引數,將其名稱與每個添加引數的名稱相匹配——在此處為 first_argument ,為了獲得引數值,需要使用 args.first_argument,
如果此腳本以下示方法執行,則輸出為 10:
python scripy_4.py 10
但如果腳本在沒有引數的情況下執行,則將輸出以下資訊:
usage: scripy_4.py [-h] first_argument
scripy_4.py: error: the following arguments are required: first_argument
最后,如果我們使用 -h 選項執行腳本,輸出將如下所示:
usage: scripy_4.py [-h] first_argument
positional arguments:
first_argument this is the string text in connection with first_argument
optional arguments:
-h, --help show this help message and exit
默認情況下,argparse 將提供的選項視為字串,因此,如果引數不是字串,則應使用 type 選項,使用 script_5.py 腳本,其中添加了兩個引數,這兩個引數是 int 型別:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("first_number", help="first number to be added", type=int)
parser.add_argument("second_number", help="second number to be added", type=int)
args = parser.parse_args()
print("args: '{}'".format(args))
print("the sum is: '{}'".format(args.first_number + args.second_number))
args_dict = vars(parser.parse_args())
print("args_dict dictionary: '{}'".format(args_dict))
print("first argument from the dictionary: '{}'".format(args_dict["first_number"]))
在前面的示例中,通過呼叫 vars() 函式將引數存盤在字典中:
args_dict = vars(parser.parse_args())
print("args_dict dictionary: '{}'".format(args_dict))
print("first argument from the dictionary: '{}'".format(args_dict["first_number"]))
如果不帶引數執行腳本:
python script_5.py
則輸出如下:
usage: scripy_5.py [-h] first_number second_number
scripy_5.py: error: the following arguments are required: first_number, second_number
此外,如果我們使用 -h 選項執行腳本:
python script_5.py --help
輸出將如下所示:
usage: scripy_1.py [-h] first_number second_number
positional arguments:
first_number first number to be added
second_number second number to be added
optional arguments:
-h, --help show this help message and exit
如果此腳本以如下方式執行:
python script_5.py 123 456
則輸出如下:
args: 'Namespace(first_number=123, second_number=456)'
the sum is: '579'
args_dict dictionary: '{'first_number': 123, 'second_number': 456}'
first argument from the dictionary: '123'
更多 argparse 的高級介紹可以在官方檔案中看到,其中包括了大量示例,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/295221.html
標籤:其他
