有時候,當我們去寫一些系統的管理工具,或者是做前期開發中代碼的邏輯調試時需要命令行接口,我們可以使用命令行傳參的形式去實現。這樣便於執行,若需要與其他程序集成,也是一個不錯的選擇。
本節我們討論用python如何實現符合UNIX/POSIX標准的命令。首先介紹argpase模塊的使用方法,最后通過一個Linux環境上實現文件回收站的示例展示argpases方法的使用。
1. 解析命令行參數模塊
python中有3個內建的模塊處理命令行參數。
第一個是:getopt,該模塊只能處理簡單的命令行參數,我們在此不做介紹,感興趣的同學呢,可以參考官方文檔學習:https://docs.python.org/2/library/getopt.html#module-getopt
第二個是:optparse,該模塊功能強大,易於是用,可以方便的生成標准的UNIX/POSIX協議格式的命令,但是他被argparse所取代,python2.7之后棄用。
第三個是:argparse,它能更容器的編寫標准的,用戶友好的命令行接口,argarse能自動生成幫助以及用戶參數錯誤的提示。官方文檔:https://docs.python.org/2/library/argparse.html#module-argparse
2. arggarse 介紹
首先以一個例子開始:將參數求和,並將結構答應到文件。
import argparse
import sys
if __name__ == '__main__':
# eg:將命令行的參數求和,並將結果寫入文件。
parser = argparse.ArgumentParser(
prog="Anliu", #項目名字,默認是sys.args[0]
#usage="", #用法說明,默認是從參數中自動生成的,例如:Anliu [-h] [--log LOG] int [int ...]
description='sum the integers at the command line', #項目描述
epilog="xxx", #參數后的文本描述
parents="",
#formatter_class="",
#prefix_chars="re" #可選參數前綴的字符。
#fromfile_prefix_chars=""
#argument_default="-r",
conflict_handler="error", #如何處理沖突的字符串。
add_help="False",
allow_abbrev="False" #容許長選項縮寫。
)
parser.add_argument(
'integers', metavar='int', nargs='+', type=int,
help='an integer to be summed')
parser.add_argument(
'--log', default=sys.stdout, type=argparse.FileType('w'),
help='the file where the sum should be written')
parser.add_argument(
"-d", "--deleteMemoryRemain",
)
args = parser.parse_args()
args.log.write('%s' % sum(args.integers))
args.log.close()
該模塊包含的方法解釋:
# 命令行解析庫
# 此模塊是一個受optparse啟示的命令行解析庫。
# 處理可選擇參數和位置參數。
# 生成信息量大的使用消息。
# 支持分配給自解析器的解析。
#
# 這個模塊包括的公共方法有:
# - ArgumentParser --命令行解析的主要入口點。如上面的示例所示,
# add_argument()方法用於使用可選參數和位置參數的操作填充解析器。
# 然后調用parse_args()方法將命令行中的args轉換為具有屬性的對象。
#
# - ArgumentError --ArgumentParser對象在解析器操作出錯時引發的異常。
# 解析命令行時引發的錯誤由ArgumentParser捕獲並作為命令行消息發出。
#
# - FileType --用於定義要創建的文件類型的工廠。
# 如上例所示,FileType的實例通常作為add_argument()調用的type=參數傳遞。
#
# - Action --解析器操作的基類。
# 通常,通過向add_argument()的action=參數傳遞“store_true”或“append_const”等字符串來選擇操作。
# 但是,為了更好地定制ArgumentParser操作,可以定義操作的子類並將其作為Action=參數傳遞。
# -HelpFormatter、RawDescriptionHelpFormatter、RawTextHelpFormatter、ArgumentDefaultsHelpFormatter
# --可以作為Formatter\u class=參數傳遞給ArgumentParser構造函數的格式化程序類。
# HelpFormatter是默認值,
# RawDescriptionHelpFormatter和RawTextHelpFormatter告訴解析器不要更改幫助文本的格式,
# ArgumentDefaultsHelpFormatter將有關參數默認值的信息添加到幫助中。
# 此模塊中的所有其他類都被視為實現細節。
# (還請注意,HelpFormatter和RawDescriptionHelpFormatter僅作為對象名被視為公共的
# ——formatter對象的API仍然被視為實現細節。)
2.1 argpase 功能
(1) 處理位置參數。
(2) 支持子命令。
(3) 允許替代選項前綴,如+和/。
(4) 處理零個或多個和一個或多個樣式參數。
(5) 生成更多信息豐富的使用消息。
(6) 為自定義type和action.
2.2 創建解析器
第一步:實例化一個ArgumentParser對象,創建解析器
import os,sys
import argparse
argpaser = argparse.ArgumentParser(
description="Realize the function of file recycle bin in Linux environment")
該ArgumentParser對象將保存將命令行解析為 Python 數據類型所需的所有信息。
創建一個新ArgumentParser對象。所有參數都應作為關鍵字參數傳遞:
if __name__ == '__main__':
parser = argparse.ArgumentParser(
#prog="Anliu", #項目名字,默認是sys.args[0]
#usage="", #用法說明,默認是從參數中自動生成的,例如:Anliu [-h] [--log LOG] int [int ...]
#description='sum the integers at the command line', #參數之前項目描述
#epilog="xxx", #參數后的文本描述
#parents="", #ArgumentParser還應包括其參數的對象列表
#formatter_class="", #用於自定義幫助輸出的類
#prefix_chars="+" #可選參數前綴的字符。
#fromfile_prefix_chars="", #該字符集的前綴文件從額外的參數應該讀(默認值:None)
#argument_default="-r", #為參數的全局默認值(默認值:None)
#conflict_handler="error", # 解決沖突選項的策略(通常是不必要的)
#add_help="False", #添加-h/--help選項解析器(默認值:True)
#allow_abbrev="False" #容許長選項縮寫。
)
2.2.1 prog的使用
默認情況下,使用的的sys.args[0]的值:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-r", help="test ...")
args = parser.parse_args()
執行結果:
PS E:\python 學習\mode_st> python .\myargparse.py -h
usage: myargparse.py [-h] [-r R]
optional arguments:
-h, --help show this help message and exit
-r R test ...
usage的項目名為文件的名字。
當我修改后:
import argparse
parser = argparse.ArgumentParser(
prog="Anliu"
)
parser.add_argument("-r", help="test ...")
args = parser.parse_args()
執行結果:
PS E:\python 學習\mode_st> python .\myargparse.py -h
usage: Anliu [-h] [-r R]
optional arguments:
-h, --help show this help message and exit
-r R test ...
2.2.2 usage的使用
默認情況下,ArgumentParser根據它包含的參數計算使用消息:
PS E:\python 學習\mode_st> python .\myargparse.py -h
usage: Anliu [-h] [-r R]
optional arguments:
-h, --help show this help message and exit
-r R test ...
修改后:
import argparse
parser = argparse.ArgumentParser(
prog="Anliu",
usage="%(prog)s [option]",
)
parser.add_argument("-r", help="test ...")
args = parser.parse_args()
執行結果:
PS E:\python 學習\mode_st> python .\myargparse.py -h
usage: Anliu [option]
optional arguments:
-h, --help show this help message and exit
-r R test ...
2.2.3 description
大多數對ArgumentParser構造函數的調用將使用 description=關鍵字參數。該參數簡要描述了程序的作用和工作方式。在幫助消息中,描述顯示在命令行用法字符串和各種參數的幫助消息之間:
默認情況下,描述將被換行以適應給定的空間。
import argparse
parser = argparse.ArgumentParser(
prog="Anliu",
usage="%(prog)s [option]",
description="This is test of myargparse."
)
parser.add_argument("-r", help="test ...")
args = parser.parse_args()
執行結果:
PS E:\python 學習\mode_st> python .\myargparse.py -h
usage: Anliu [option]
This is test of myargparse.
optional arguments:
-h, --help show this help message and exit
-r R test ...
2.2.4 epilog
一些程序喜歡在參數描述之后顯示程序的附加描述。可以使用以下epilog= 參數指定此類文本.
import argparse
parser = argparse.ArgumentParser(
prog="Anliu",
usage="%(prog)s [option]",
description="This is test of myargparse.",
epilog="myargparse end."
)
parser.add_argument("-r", help="test ...")
args = parser.parse_args()
執行結果:
PS E:\python 學習\mode_st> python .\myargparse.py -h
usage: Anliu [option]
This is test of myargparse.
optional arguments:
-h, --help show this help message and exit
-r R test ...
myargparse end.
2.2.5 parent 的使用
有時,多個解析器共享一組公共參數。無需重復這些參數的定義,而是 可以使用具有所有共享參數並傳遞給parents=參數 to的單個解析器。
import argparse
parents_parser = argparse.ArgumentParser(add_help=False)
parents_parser.add_argument("-i",help="This test of parents")
parser = argparse.ArgumentParser(
prog="Anliu",
usage="%(prog)s [option]",
description="This is test of myargparse.",
epilog="myargparse end.",
parents=[parents_parser],
)
parser.add_argument("-r", help="test ...")
args = parser.parse_args()
執行結果:
PS E:\python 學習\mode_st> python .\myargparse.py -h
usage: Anliu [option]
This is test of myargparse.
optional arguments:
-h, --help show this help message and exit
-i I This test of parents
-r R test ...
myargparse end.
2.2.6 formatter_class的使用
ArgumentParser對象允許通過指定替代格式類來自定義幫助格式。目前,有三個這樣的類:
類argparse.RawDescriptionHelpFormatter
類argparse.RawTextHelpFormatter
類argparse.ArgumentDefaultsHelpFormatter
前兩個允許更多地控制文本描述的顯示方式,而最后一個自動添加有關參數默認值的信息。
默認情況下,ArgumentParser對象在命令行幫助消息中對描述和結尾文本進行換行:
import argparse
parents_parser = argparse.ArgumentParser(add_help=False)
parents_parser.add_argument("-i",help="This test of parents")
parser = argparse.ArgumentParser(
prog="Anliu",
usage="%(prog)s [option]",
description='''
-------------begin------------
This is test of myargparse.
The program used to test argparse.
please not repeat origro argarse.
''',
epilog='''
--------------end--------------
myargparse end.
Bey.
''',
parents=[parents_parser],
)
parser.add_argument("-r", help="test ...")
args = parser.parse_args()
執行結果:
PS E:\python 學習\mode_st> python .\myargparse.py -h
usage: Anliu [option]
-------------begin------------ This is test of myargparse. The program used to
test argparse. please not repeat origro argarse.
optional arguments:
-h, --help show this help message and exit
-i I This test of parents
-r R test ...
--------------end-------------- myargparse end. Bey.
傳遞RawDescriptionHelpFormatterasformatter_class= 表示描述和結語已經正確格式化,不應換行:
import argparse
parents_parser = argparse.ArgumentParser(add_help=False)
parents_parser.add_argument("-i",help="This test of parents")
parser = argparse.ArgumentParser(
prog="Anliu",
usage="%(prog)s [option]",
formatter_class=argparse.RawDescriptionHelpFormatter,
description='''
-------------begin------------
This is test of myargparse.
The program used to test argparse.
please not repeat origro argarse.
''',
epilog='''
--------------end--------------
myargparse end.
Bey.
''',
parents=[parents_parser],
)
parser.add_argument("-r", help="test ...")
args = parser.parse_args()
執行結果:
PS E:\python 學習\mode_st> python .\myargparse.py -h
usage: Anliu [option]
-------------begin------------
This is test of myargparse.
The program used to test argparse.
please not repeat origro argarse.
optional arguments:
-h, --help show this help message and exit
-i I This test of parents
-r R test ...
--------------end--------------
myargparse end.
Bey.
RawTextHelpFormatter為各種幫助文本保留空格,包括參數描述。但是,多個新行被替換為一個。如果您希望保留多個空行,請在換行符之間添加空格。
另一個可用的格式化程序類ArgumentDefaultsHelpFormatter將添加有關每個參數的默認值的信息:
import argparse
parents_parser = argparse.ArgumentParser(add_help=False)
parents_parser.add_argument("-i",help="This test of parents")
parser = argparse.ArgumentParser(
prog="Anliu",
usage="%(prog)s [option]",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
parents=[parents_parser],
)
parser.add_argument("-r", help="test ...", default="remove")
args = parser.parse_args()
執行結果:
PS E:\python 學習\mode_st> python .\myargparse.py -h
usage: Anliu [option]
optional arguments:
-h, --help show this help message and exit
-i I This test of parents (default: None)
-r R test ... (default: remove)
2.2.7 prefix_chars使用
大多數命令行選項將-用作前綴,這個前綴就可以在這里修改。因為約定俗稱,不建議修改。
2.2.8 argument_default使用
指定默認值,當參數沒有定義是使用默認。
2.2.9 conflict_handler的使用
ArgumentParser對象不允許具有相同選項字符串的兩個操作。默認情況下,ArgumentParser如果嘗試使用已在使用的選項字符串創建參數,則對象會引發異常:
import argparse
with open("args.txt","w") as f:
f.write("-f\nbar")
parents_parser = argparse.ArgumentParser(add_help=False)
parents_parser.add_argument("-i",help="This test of parents")
parser = argparse.ArgumentParser(
prog="Anliu",
usage="%(prog)s [option]",
fromfile_prefix_chars="args.txt",
parents=[parents_parser],
)
parser.add_argument("-r", help="test ...", default="remove")
parser.add_argument("-i",help="This test of parser")
args = parser.parse_args()
執行結果:
PS E:\python 學習\mode_st> python .\myargparse.py -h
Traceback (most recent call last):
raise ArgumentError(action, message % conflict_string)
argparse.ArgumentError: argument -i: conflicting option string: -i
有時(例如,在使用parents 時)用相同的選項字符串簡單地覆蓋任何舊參數可能很有用。要獲得此行為,'resolve'可以將該值 提供給 的conflict_handler=參數 ArgumentParser:
import argparse
with open("args.txt","w") as f:
f.write("-f\nbar")
parents_parser = argparse.ArgumentParser(add_help=False)
parents_parser.add_argument("-i",help="This test of parents")
parser = argparse.ArgumentParser(
prog="Anliu",
usage="%(prog)s [option]",
fromfile_prefix_chars="args.txt",
conflict_handler="resolve",
parents=[parents_parser],
)
parser.add_argument("-r", help="test ...", default="remove")
parser.add_argument("-i",help="This test of parser")
args = parser.parse_args()
執行結果就正常了。
PS E:\python 學習\mode_st> python .\myargparse.py -h
usage: Anliu [option]
optional arguments:
-h, --help show this help message and exit
-r R test ...
-i I This test of parser
2.2.10 add_help的使用
默認情況下, ArgumentParser 對象添加一個選項,該選項僅顯示解析器的幫助消息。有時,禁用此幫助選項的添加可能會很有用。這可以通過False作為add_help=參數傳遞給ArgumentParser。
2.3 添加參數
ArgumentParser通過調用add_argument()方法來填充有關程序參數的信息。通常,這些調用告訴ArgumentParser如何在命令行上獲取字符串並將它們轉換為對象。該信息在parse_args()被調用時被存儲和使用。
上面的示例中已經大量使用。
接下來我們討論parse_args()的參數。
name or flags --Either a name or a list of option strings, e.g. foo or -f, --foo.
action --The basic type of action to be taken when this argument is encountered at the command line.
nargs --The number of command-line arguments that should be consumed.
const --A constant value required by some action and nargs selections.
default --The value produced if the argument is absent from the command line.
type --The type to which the command-line argument should be converted.
choices --A container of the allowable values for the argument.
required --Whether or not the command-line option may be omitted (optionals only).
help --A brief description of what the argument does.
metavar --A name for the argument in usage messages.
dest --The name of the attribute to be added to the object returned by parse_args().
參數列表與釋義:
參數 | 選項 | 釋義 |
---|---|---|
action | store | 存儲參數的值,是默認操作。 |
store_const | 指定由canst關鍵字指定的值。 | |
store_true | 轉存值true | |
store_false | 轉存值false | |
append | 轉存為一個列表,這對一次轉存多個選項很有用。 | |
append_const | 轉存為一個列表,並將const執行的關鍵字參數的值附件到列表。 | |
count | 計算關鍵字出現的次數,對於提高詳細級別的計算很有用。 | |
version | 調運version關鍵字參數並打印。 | |
nargs | N(一個整數) | 選擇命令行參數個數,並將其收集到一個列表。 |
? | 容許默認參數,不指定則為空,不接受default指定,需要const指定。 | |
* | 將多個參數收集到一個列表。 | |
+ | 和*類似,但是需要至少一個參數。 | |
argparse.REMAINDER | 所有剩余的命令行參數都收集到一個列表中。 | |
default | 在命令行中可以省略所有可選參數和一些位置參數。 | |
type | float,int,argparse.FileType(''),自定義 | 參數的類型檢查和類型轉換。 |
choices | 支持in操作符的對象都可以作為choices 值傳遞,所以dict對象、set對象、自定義容器等都被支持。 | 選擇容器對象。 |
required | True,false | 設置必選項 |
help | 打印幫助信息。 |
下面試一些例舉,供大家參考練習。
import argparse
import os, sys
import math
class myaction(argparse.Action):
def __init__(self, option_strings, dest, nargs=None, **kwargs):
if nargs is not None:
raise ValueError("nargs not allowed")
super(myaction, self).__init__(option_strings, dest, **kwargs)
def __call__(self, parser, namespace, values, option_string=None):
print('%r %r %r' % (namespace, values, option_string))
setattr(namespace, self.dest, values)
def perfect_square(string):
value = int(string)
sqrt = math.sqrt(value)
if sqrt != int(sqrt):
msg = "%r is not a perfect square" % string
raise argparse.ArgumentTypeError(msg)
return value
parser = argparse.ArgumentParser(
prog="Anliu",
usage="%(prog)s [option]",
)
parser.add_argument("-n1", action="store")
parser.add_argument("-n2", action="store_const", const=42)
parser.add_argument("-p1", action="store_false")
parser.add_argument("-p2", action="store_true")
parser.add_argument("-p3", action="append")
parser.add_argument("--str", dest="types", action="append_const", const=str)
parser.add_argument("--int", dest="types", action="append_const", const=int)
parser.add_argument("-v", action="count", help="This is a test of anliu")
parser.add_argument("--version", action="version", version='%(prog)s 1.0')
parser.add_argument("-m", action=myaction)
parser.add_argument("-t", nargs=2)
parser.add_argument("-f1", nargs="?", default=2)
parser.add_argument("-f2", nargs="?", const=1, default=2)
parser.add_argument("-a", required=True)
parser.add_argument("-b", nargs="?", type=argparse.FileType("r"), default=sys.stdin)
parser.add_argument("-c", nargs="?", type=argparse.FileType("w"), default=sys.stdout)
parser.add_argument("-d", nargs="*")
parser.add_argument("-e", nargs="+")
parser.add_argument("args", nargs=argparse.REMAINDER)
parser.add_argument("-g", default=10.2, type=int)
parser.add_argument("-i", default=argparse.SUPPRESS)
parser.add_argument("-j", type=perfect_square)
parser.add_argument("-k", choices=["move","delete","get"], help="The option is %(prog)s, %(default)s")
parser.add_argument("-l", dest="abc")
parser.add_argument('--foo', default=argparse.SUPPRESS)
args = parser.parse_args()
print(args)
2.4 解析參數
parse_args()方法將參數字符串轉換為對象並將它們分配為命名空間的屬性。返回填充的命名空間。
args - 要解析的字符串列表。默認值取自 sys.argv.
命名空間 - 獲取屬性的對象。默認是一個新的空 Namespace對象。
2.5 子命令
許多程序分割它們的功能分成若干子命令。
當程序執行需要不同類型命令行參數的多個不同功能時,以這種方式拆分功能可能是一個特別好的主意。 支持使用方法創建此類子命令 。該方法通常不帶參數調用,並返回一個特殊的操作對象。這個對象有一個方法,它接受一個命令名稱和任何構造函數參數,並返回一個可以像往常一樣修改的對象。
import argparse
# create the top-level parser.
parser = argparse.ArgumentParser(
prog="Anliu"
)
parser.add_argument("-foo", action="store_true",help="foo help.")
subparser = parser.add_subparsers(help="sub_command help.")
# create the parse for the "a" command.
parser_a = subparser.add_parser('a', help="a help.")
parser_a.add_argument("bar", type=int, help="bar help.")
# create the parse for the "b" command.
parser_b = subparser.add_parser('b', help="b help.")
parser_b.add_argument("--baz", choices="XYZ", help="baz help.")
#parse some argument lists.
args = parser.parse_args()
print(args)