Python命令列選項引數解析策略
概述
在Python的專案開發過程中,我們有時需要為程式提供一些可以通過命令列進行呼叫的介面。不過,並不是直接使用 command + 當前檔案 就ok的,我們需要對其設定可選的各種各樣的操作型別。所以,這種情況下我們就有必要對傳入的引數進行解析操作。下面就此問題提出幾種不同的解決策略,希望於你有益。
版權說明
目錄
樸素字串匹配方案
分析
其實此方法可以很直接地表達程式猿們在邏輯這條路走了多遠。當然,這並沒有包含任何的不敬。
這的確是一種方案,甚至可以說是一種演算法。因為其直截了當,所以在程式開發初期,本人也是如此樂此不疲。除了完全的一個一個的命令之外,我們還可以對引數進行json封裝,這樣就更加體貼了。
關於,這一點我想也不用多說什麼的了。還是留一些時間給後面的兩種解決方案比較妥當。不過還是可以說說此方案的優點與缺點。
優點
- 針對不同的引數進行不同的處理,針對性強
缺點
- 因為其針對性太強,所以其複用性太差
getopt模組
簡介
此模組是python內建的一個模組。該模組是專門用來處理命令列引數的。
其基本使用格式如下:
opts, args = getopt.getopt(args, shortopts, longopts = [])
對於getopt()方法的第一個引數,就是我們通過命令列傳入的引數。不過這裡也有一個值得注意的地方,我需要對引數列表進行切片處理。因為我們獲得的第一個(args[0])命令列引數是當前檔名稱,這並不是我們需要的。
對於getopt()的第二個引數,是shortopts
shortopts比如:-h
longopts比如:–help
shortopts是以’-‘為字首的,longopts是以”- -“為字首的.
我們也可以單獨使用短引數。基本使用格式如下:
opts, args = getopt.getopt(sys.argv[1:], "ld:")
實戰用例
from __init__ import *
def usage():
print 'prama_config.py usage:'
print '-h, --help: Print help message.'
print '-v, --version: Print script version'
print '-o, --output: Input an output verb'
print '-m, --message: Send a message to someone.'
print '--foo: Test option '
print '--fre: Another test option'
def version():
print 'prama_config.py 1.0.1'
def output(args):
print 'Hello, %s' % args
def message(sender, receiver, msg):
print("{0} Send a message to {1}, content is \'{2}\'.".format(sender, receiver, msg))
def main(argv):
try:
opts, args = getopt.getopt(argv[1:], 'hvom:', ['help=', 'message=', 'foo=', 'fre='])
except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(2)
for o, a in opts:
if o in ('-h', '--help'):
usage()
sys.exit(1)
elif o in ('-v', '--version'):
version()
sys.exit(0)
elif o in ('-o', '--output'):
output(a)
sys.exit(0)
elif o in ('-m', '--message'):
message(a, args[0], args[1])
sys.exit(0)
else:
print 'unhandled option'
sys.exit(3)
if __name__ == '__main__':
main(sys.argv)
OptionParser模組
簡介
前面說到getopt,不過getopt太小了,而且從程式碼的角度看,面向過程的嫌疑很重。相對getopt,OptionParser就顯得比較專業級了。OptionParser通過parser.add_option()新增選項引數,再通過parser.parse_args()進行解析引數選項。整個過程很面向物件。
對於OptionParser還有一個優點在於,我們不需要為OptionParser設定help的選項,help選項已經被內建到模組當中去了。
parser.add_option()引數說明
- action: action是parse_args() 方法的引數之一,它指示 optparse 當解析到一個命令列引數時該如何處理。actions 有一組固定的值可供選擇,預設是’store ‘,表示將命令列引數值儲存在 options 物件裡。action的取值有store, store_true, store_false三個;
- dest: dest是儲存的變數,命令列的執行命令將會儲存到dest指定的值當中。比如,下面程式碼中的-p命令,就會被儲存到dest=”pdcl”指定的options的pdcl變數中;
- default: 用於設定上面dest中儲存變數的預設值。比如下面的程式碼中,我們就將預設值打成了False。那麼,我們通過options.pdclp這個變數訪問到的值就是False;
- type: 用於指定dest中儲存變數值的資料型別。預設的資料型別為string;
- help: 用於指定當前命令的提示資訊。
實戰用例
from optparse import OptionParser
parser = OptionParser()
parser.add_option(
"-p", "--pdbk",
action="store_true", # 指示 optparse 當解析到一個命令列引數時該如何處理
dest="pdcl", # 儲存的變數
default=False,
help="write pdbk data to oracle db"
)
parser.add_option(
"-z", "--zdbk",
action="store_true",
dest="zdcl", # 儲存的變數
default=False,
help="write zdbk data to oracle db"
)
parser.add_option(
"-f", "--file", # 操作指令
action="store",
dest="filename", # 儲存的變數
type="string", # 變數型別
help="write report to FILE", # 顯示的幫助資訊
metavar="FILE" # 儲存變數的值
)
parser.add_option(
"-q", "--quiet",
action="store_false",
dest="verbose",
default=True,
help="don't print status messages to stdout"
)
(options, args) = parser.parse_args()
if options.pdcl is True:
print 'pdcl is true'
if options.zdcl is True:
print 'zdcl is true'
if options.filename is not None:
print("filename={0}".format(options.filename))
print(args)
通過對上面三種引數解析策略的說明,可以看到這裡使用OptionParser模組進行解析是最佳方式。