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)