1. 程式人生 > 實用技巧 >python 命令列引數sys.grgv和getopt模組

python 命令列引數sys.grgv和getopt模組

在執行程式時,可能需要根據不同的條件,輸入不同的命令列選項來實現不同的功能。

目前有短選項和長選項兩種格式。短選項格式為"-"加上單個字母選項;長選項為"--"加上一個單詞。

命令列引數分為選項(opts)和引數(args)

sys.argv獲得命令列引數

import sys

print(sys.argv)

執行程式

D:\projects\runcmd>python test.py -a -b args1 --cc --dd=args2 file1

['test.py', '-a', '-b', 'args1', '--cc', '--dd=args2', 'file1']

可見,所有命令列引數以空格為分隔符,都儲存在了sys.argv列表中。其中第1個為指令碼的檔名。

選項的寫法要求

短格式

"-"號後面要緊跟一個選項字母。

如果還有此選項的附加引數,可以用空格分開,也可以不分開。長度任意,可以用引號。

-o         #只有選項,沒有引數,用作功能開關

-oa        #選項加引數,沒有空格

-obbbb        #選項加引數,沒有空格

-o bbbb        #選項加引數,有空格

-o "a b"        #選項加引數,引數有空格需要加引號

長格式

"--"號後面要跟一個單詞。

如果還有此選項的附加引數,後面要緊跟"=",再加上引數。"="號前後不能有空格。

--help=file1

getopt分析命令列引數

 

由sys.argv獲得命令列引數以後,使用getopt模組進行分析

語法

getopt(args, shortopts, longopts=[])

第一個引數args為要分析的引數列表,一般設定為sys.argv[1:]

第二個引數為短格式選項

  • 當只有選項,沒有引數時,即-h 樣式,在分析串中寫入該字元,h或者-h
  • 當選項有引數時,即-f file1樣式,在分析串中寫入該字元加冒號,f:或者-f:

第三個引數為長格式選項

當只有選項,沒有引數時,即--help樣式,在分析串中寫入該引數。help

當選項有引數時,即--file=file1時,在分析串中吸入該引數加等號。file=

返回值

opts, args兩個列表

opts為分析出的格式資訊。opts是一個兩元組的列表。每個元素為:(選項串,附加引數)。如果沒有附加引數則為空字串。

args為不屬於格式資訊的剩餘的命令列引數,即不是按照getopt()裡面定義的長或短選項字元和附加引數以外的資訊。

示例1:getopt分析指令碼引數

程式碼:

import sys,getopt

print(sys.argv)

opts, args = getopt.getopt(sys.argv[1:], '-a-b:', ['cc', 'dd='])

print('opts',opts)

print('args',args)

 

執行:

D:\projects\runcmd>python test.py -a -b args1 --cc --dd=args2 file1

['test.py', '-a', '-b', 'args1', '--cc', '--dd=args2', 'file1']

opts [('-a', ''), ('-b', 'args1'), ('--cc', ''), ('--dd', 'args2')]

args ['file1']

示例2:getopt進一步分析指令碼引數,進行下一步處理

程式碼:

import sys,getopt
print(sys.argv)
opts, args = getopt.getopt(sys.argv[1:], 'hi:', ['help', 'ip='])
print('opts',opts)
print('args',args)
for opt_name,opt_value in opts:
if opt_name in ['-h','--help']:
print('help doc')
sys.exit()
if opt_name in ['-i','--ip']:
print(opt_value)
sys.exit()

 

執行:

D:\projects\runcmd>python test.py -h

['test.py', '-h']

opts [('-h', '')]

args []

help doc

 

D:\projects\runcmd>python test.py -i 192.168.1.1

['test.py', '-i', '192.168.1.1']

opts [('-i', '192.168.1.1')]

args []

192.168.1.1

示例3:各種用法

直接執行指令碼,不加選項和引數,顯示幫助資訊

if len(sys.argv[1:]) == 0:
print(helpdoc)
sys.exit()

執行指令碼,加-h或者--help選項,顯示幫助資訊

opts, args = getopt.getopt(sys.argv[1:], 'hsf:')

argsdict = {}
for opt_name, opt_value in opts:
argsdict[opt_name]=opt_value

if  '-h' in argsdict: #幫助資訊
print(helpdoc)
sys.exit()

引數資訊不足,顯示幫助資訊

opts, args = getopt.getopt(sys.argv[1:], 'hsf:')

 

if len(args) < 5:  # file,port,username,passeord,command1,[command2]...
print(helpdoc)
sys.exit()

獲取引數資訊

opts, args = getopt.getopt(sys.argv[1:], 'hsf:')

file, port, username, password, *commands = args

 

選項列表轉化為字典

opts, args = getopt.getopt(sys.argv[1:], 'hsf:')

for opt_name, opt_value in opts:
argsdict[opt_name]=opt_value

 

選項資訊不足,提示缺少選項


ip,port = None,None
for
opt_name,opt_value in opts:
if opt_name in ['-h', '--help']:
print('help doc')
sys.exit()
if opt_name in ['-i', '--ip']: ip = opt_value
if opt_name in ['--port']: port = opt_value


if not ip:
print('ip not exit')
sys.exit()
if not port:
print('port not exit')
sys.exit()

 

處理選項與引數

處理選項

  • 可以將選項列表轉化為字典,然後判斷選項是否在字典中

    帶引數的選項使用vaule = dict.get(key),

    如果存在則返回引數值,如果不存在引數值為None,也可以dict.get(key,default)指定預設引數值

    不帶引數的選項使用in判斷

  • 可以直接處理(選項,引數)元組組成的列表,迴圈處理

    為了防止執行指令碼時,提交選項不足,使得引數未獲取到值,可以先賦值變數值為空字串或None,

    然後再判斷變數值,如果為空字串或者None,中斷程式,提示引數不足

處理引數

引數被收集到args列表中,是順序的,所以針對列表

  • len()判斷引數個數
  • 如果不需要進一步處理,直接傳參列表args,或者列表解包*args
  • 如果需要進一步處理,列表解包,file, port, username, password, *commands = args,再傳參
  • 函式fun形參為arge形式,表示只接受一個引數,呼叫時傳入列表,fun(commands)
  • 函式fun形參為*arge形式,表示接受多個引數,呼叫時傳入解包列表,fun(*command)

示例4:模板

程式碼:

import sys,getopt

def fun(ip,port,args):
if flag :
print('True',ip,port,args)
else:
print('false',ip,port,args)

#不加引數提示幫助資訊,或者執行函式
if len(sys.argv[1:]) == 0:
print('help doc')
sys.exit()
try: #getopt函式放到try裡面,防止指令碼呼叫時,出現不期望的引數,會報錯
opts, args = getopt.getopt(sys.argv[1:], 'hsi:', ['help','ip=','port='])
except Exception as e:
print(e)
sys.exit()
#先分析選項
ip,port = None,None #提前賦值變數,然後分析getopt的返回結果,再對變數值進行判斷,適用於必須的選項
flag = False #標誌位,先置於False,再分析getopt的返回結果,如果存在標誌位,再置為True,再在函式中判斷標誌位,作出不同的響應
for opt_name,opt_value in opts:
if opt_name in ['-h', '--help']: #幫助資訊
print('help doc')
sys.exit()
if opt_name in ['-i', '--ip']: ip = opt_value #必須引數
if opt_name in ['--port']: port = opt_value #必須引數
if opt_name in ['-s']:flag = True #功能性引數,標誌位
#
if not ip:
print('ip not exit')
sys.exit()
if not port:
print('port not exit')
sys.exit()

#再分析引數
if len(args) < 1: # 判斷引數個數
print('helpdoc')
sys.exit()
else:
fun(ip,port,args) #如果選項都存在且不為空字串,引數個數也齊全,再執行函式

執行:

D:\projects\runcmd>python test.py -i 192.168.0.1 --port=22 file1

false 192.168.0.1 22 ['file1']

 

D:\projects\runcmd>python test.py -s -i 192.168.0.1 --port=22 file1

True 192.168.0.1 22 ['file1']

 

D:\projects\runcmd>python test.py -i 192.168.0.1 --port=22 file1 file2

false 192.168.0.1 22 ['file1', 'file2']

 

D:\projects\runcmd>python test.py -s -i 192.168.0.1 --port=22 file1 file2

True 192.168.0.1 22 ['file1', 'file2']