python常用模塊——argparse


有時候,當我們去寫一些系統的管理工具,或者是做前期開發中代碼的邏輯調試時需要命令行接口,我們可以使用命令行傳參的形式去實現。這樣便於執行,若需要與其他程序集成,也是一個不錯的選擇。
本節我們討論用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)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM