主頁 > 軟體設計 > Python 命令列引數詳解

Python 命令列引數詳解

2021-08-21 08:38:20 軟體設計

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

在引數串列中沒有找到所傳遞引數,或選項的需要的引數為空時會觸發該例外,例外的引數是一個字串,表示錯誤的原因,屬性 msgopt 為相關選項的錯誤資訊,
在上述代碼中添加例外處理,檢查此錯誤資訊:

# ...
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

標籤:其他

上一篇:淘汰過時的工具也有錯?微軟的 Blazor 框架會是下一個 SilverLight?

下一篇:【C語言初階】一次性搞定分支陳述句和回圈陳述句(干活滿滿+建議收藏)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more