Featured image of post Python系列: 三種引入外部參數的方法

Python系列: 三種引入外部參數的方法

Background photo by Artturi Jalli on Unsplash

撰寫python script時,變數內容若能隨使用者彈性更改,可提升程式實用性;本文介紹三種常用的引入外部參數模組: sys, argparse, 以及 click,文章將介紹模組/套件的使用方式,撰寫相同輸出的實例,並分析優缺點以供讀者參考。

sys 模組

sys 屬於 python 內建模組,其下的 sys.argv[index] 是最基本的引入方式。

sys.argv 的運行方式,是把bash command line 中輸入的指令存成一個list,並引入對應index的內容名稱。

Index 對照說明

假設撰寫名為 test.py 的 script:

1
2
3
4
5
6
import sys

input_var1 = sys.argv[1] 

print("sys index 0 : " + sys.argv[0])
print("sys index 1 : " + input_var1)

在 linux bash 執行 python script :

1
python3 test.py apple

注意: sys 會將 script 名稱視為 sys.argv[0] 也就是index 0 不能使用,而外部參數的 index 會從 1 開始

綜合上述觀念,bash 輸出:

1
2
sys index 0 : test.py
sys index 1 : apple

實例

撰寫名為 test.py 的 script:

1
2
3
4
5
6
import sys

fruit = sys.argv[1]
price = sys.argv[2]

print("The price of " + fruit + " is " + price)

bash 輸入參數 python3 test.py apple 20 得到

1
The price of apple is 20

Comments

sys 方式多用於測試階段,或是簡單的個人專案上,若需要引入多個參數,或是有協作專案的需求,sys會面臨以下缺點:

  • index 引入很看重順序,參數太多增加錯誤機會
  • 且無法為下一個使用者解釋輸入參數的內容,降低推廣性

接下來要介紹的兩個模組,都是針對不同參數給予特定名稱,並說明參數要求,提高script的實用性。

argparse 模組

argparse 同屬於 python 內建模組,用於命令列剖析

引入模組

引入模組後先創建 ArgumentParser 物件以及設定參數

1
2
import argparse
parser = argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None)

prog: program 名稱,不指定寫 None,default 會帶入 python script 名稱 usage: 告知使用者說應該怎麼使用 program,default 會帶入 script 名稱加上所有參數 description: 一段文字說明程式功能 epilog: 添加在 --help 訊息後的補充文字

例子:

1
2
3
4
5
6
## 撰寫 test.py
import argparse

parser = argparse.ArgumentParser(prog = None,
usage = None, description = 'this is description', 
epilog = 'this is eliog')
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
## 在 bash 輸入 python3 test.py --help 會產生以下內容

usage: test.py [-h] --anno ANNO

this is description

options:
  -h, --help   show this help message and exit

this is eliog

添加參數名稱

1
2
parser.add_argument("--anno", required = T, help = "required arguments")
parser.add_argument("--input", default ="none")

-a / --anno 為自定義的參數flag,以將參數引入特殊變數內 required 執行script 必須要有的參數,default = False default 當使用者沒給此項參數,則引入預先設定的default值 help 針對參數的說明文字,使用 --help 後會顯示

將參數後的內容引入變數

args.parameter_flag 的形式引入特定參數下的內容

1
2
args = parser.parse_args()
a = str(args.anno)

實例

撰寫名為 test.py 的 script:

1
2
3
4
5
6
7
8
import argparse

parser = argparse.ArgumentParser(description = "print input friut type and their price")
parser.add_argument('-f', '--fruit', required=True, help= "name of fruit")
parser.add_argument('-p', '--price', default = 20, help = "price of item")

args = parser.parse_args()
print("The price of " + args.fruit + " is " + args.price)

bash 輸入 python3 test.py --help 查看訊息

1
2
3
4
5
6
7
8
usage: test.py [-h] -f FRUIT [-p PRICE]

print input friut type and their price

options:
  -h, --help               show this help message and exit
  -f FRUIT, --fruit FRUIT  name of fruit
  -p PRICE, --price PRICE  price of item

bash 輸入參數 python3 test.py --fruit apple --price 20 得到

1
The price of apple is 20

Comments

argparse 模組提升參數引入的複雜性與數量,增加在真實世界的使用機會;但複雜的步驟轉換(建立物件 > add_args > parse_args)讓人頭昏眼花,若能有更簡單的參數設定機制,可以減低程式撰寫的難易度

click 套件

click 官網以 creating beautiful command line interfaces 形容套件的核心功能

下載並引入套件後,只需利用 @click.command@click_option 即可產生和argparse等價的結果

實例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import click

@click.command
@click.option('-f', '--fruit','fruit', required=True, help= "name of fruit")
@click.option('-p', '--price', 'price', default = 20, help = "price of item")
def main(fruit, price):
    print("The price of " + fruit + " is " + str(price))

if __name__ == '__main__':
    main()

bash 輸入參數 python3 test.py --fruit apple --price 20 得到相同console:

1
The price of apple is 20

Comments

argparse 相比 click 語法更加簡潔,許多參數都相容,推薦新手可以直接使用click建立參數指令,但請注意 python 版本相容性,詳細可參考官網說明。

參考資料

https://docs.python.org/zh-tw/3/library/sys.html#sys.argv https://docs.python.org/zh-tw/3/howto/argparse.html https://click.palletsprojects.com/en/8.1.x/ https://myapollo.com.tw/blog/python-click/

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus