<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
通常,對於大型專案程式而言,執行程式的一個必要的步驟是正確處理命令列引數,這些命令列引數是提供給包含某種引數化資訊的程式或指令碼的引數。例如,在計算機視覺專案中,影象和不同型別的檔案通常作為命令列引數傳遞給指令碼,用於使程式可以處理不同圖片或者不同型別檔案。
命令列引數是引數化程式執行的一種常見且簡單的方法,下面主要介紹三種常見的獲取和解析命令列引數的方法。
為了處理命令列引數,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 模組來識別命令列選項。
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
在參數列中沒有找到所傳遞引數,或選項的需要的引數為空時會觸發該異常。異常的引數是一個字串,表示錯誤的原因。屬性 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
當程式中使用採用複雜引數或多個檔名時,推薦使用 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_argumentoptional 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 addedoptional 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 的高階介紹可以在官方檔案中看到,其中包括了大量範例。
到此這篇關於Python命令列引數詳解的文章就介紹到這了,更多相關Python命令列引數內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45