一、模块初解
argparse 模块是 Python 内置的用于命令项选项与参数解析的模块,可以方便地读取命令行参数。
参考代码如下
# 1. 导入模块
import argparse
def format_parser():
# 2. 定义命令行解析器对象
parser = argparse.ArgumentParser(description='参数说明') # description为help中添加说明
# 3.添加命令行参数
# 3.1 定义位置参数(命令行不可缺省)
# 注意:位置参数不能用 - 连接词
# help定义内容在帮助中显示
# choices表示参数只能在范围内的值
parser.add_argument("app_name", help="操作的app应用名称")
parser.add_argument("action", choices=["add", "del", "update"], help="可执行操作")
# 3.2 定义可选参数(命令行可缺省)
# 注意:可选参数可用 - 也可用 _ 连接词,不管什么方式获取参数值时均用 _
# action定义为store_true,表示命令行有该参数时output-report的值为True,反之为False
# default定义默认值。当参数缺省时,run-times默认为1
# type定义参数的值类型。命令行获取的参数值默认为str类型
parser.add_argument("--output-report", help="是否输出报告", action="store_true")
parser.add_argument("--run-times", help="执行次数", default=1, type=int)
# 4.从命令行中结构化解析参数
return parser.parse_args()
if __name__ == '__main__':
args = format_parser()
print(args)
# 5.获取命令行参数
print(args.action)
print(args.app_name)
print(args.output_report)
print(args.run_times)
在命令行执行文件并使用 -h 参数查看帮助说明
在命令行输入命令
二、工厂模式封装命令
实现代码
import argparse
import inspect
import os
import sys
class ArgumentParser(object):
"""参数解析
"""
USAGE = """Usage: %(ProgramName)s subcommand [options] [args]
Options:
-h, --help show this help message and exit
Type '%(ProgramName)s help <subcommand>' for help on a specific subcommand.
Available subcommands:
%(SubcmdList)s
"""
def __init__(self, subcmd_classes):
"""构造函数
"""
self.subcmd_classes = subcmd_classes
self.prog = os.path.basename(sys.argv[0])
def print_help(self):
"""打印帮助文档
"""
print(self.USAGE % {
"ProgramName": self.prog,
"SubcmdList": "\n".join(['\t%s' % it.name for it in self.subcmd_classes])
})
def parse_args(self, args):
"""解析参数
"""
if len(args) < 1:
self.print_help()
return 1
subcmd = args[0]
for it in self.subcmd_classes:
if it.name == subcmd:
subcmd_class = it
parser = it.parser
break
else:
print("invalid subcommand \"%s\"\n" % subcmd)
self.print_help()
return 1
args = parser.parse_args(args[1:])
subcmd = subcmd_class()
subcmd.main_parser = self
return subcmd, args
def get_subcommand(self, name):
"""获取子命令
"""
for it in self.subcmd_classes:
if it.name == name:
return it()
class ManagementTools(object):
"""管理工具类入口
"""
@staticmethod
def _load_cmd_from_module():
"""加载当前文件Command子类
"""
cmds = []
mod = sys.modules[__name__]
for objname in dir(mod):
obj = getattr(mod, objname)
if not inspect.isclass(obj):
continue
if obj == Command:
continue
if issubclass(obj, Command):
cmds.append(obj)
cmds.sort(key=lambda x: x.name)
return cmds
def execute(self):
"""执行入口
"""
cmds = self._load_cmd_from_module()
argparser = ArgumentParser(cmds)
parse_args = argparser.parse_args(sys.argv[1:])
if parse_args == 1:
return
subcmd, args = parse_args
return subcmd.execute(args)
class Command(object):
"""一个命令
"""
name = None
parser = None
def __init__(self):
self.main_parser = None # ArgumentParser实例化对象
def execute(self, args):
"""执行过程
"""
raise NotImplementedError()
class Help(Command):
"""帮助命令
"""
name = 'help'
parser = argparse.ArgumentParser("Display subcommand usage")
parser.add_argument('subcommand', nargs='?', help="target subcommand to display")
def execute(self, args):
"""执行过程
"""
# 如果没有在help参数后没有命令参数,直接打印自定义帮助信息
if args.subcommand is None:
self.main_parser.print_help()
return
subcmd = self.main_parser.get_subcommand(args.subcommand)
# 如果help参数后有命令参数,但不是有效,直接打印自定义帮助信息
if subcmd is None:
self.main_parser.print_help()
return
# 如果help参数后有命令参数,且是有效,直接命令参数的帮助信息
subcmd.parser.print_help()
class RunTest(Command):
"""执行用例
"""
name = 'runtest'
app_names = ["test", "demo"]
report_type = ["stream", "html"]
parser = argparse.ArgumentParser(description='参数说明')
parser.add_argument("app_name", help="app名称,可输入:" + ",".join(app_names))
parser.add_argument("--report-type", help="报告类型,可输入:" + ",".join(report_type))
def execute(self, args):
"""执行过程
"""
app_name = args.app_name
r_type = args.report_type
print(f"执行app:{app_name}")
print(f"生成报告类型:{r_type}")
class CreateApp(Command):
"""创建应用
"""
name = 'createapp'
parser = argparse.ArgumentParser(description='参数说明')
parser.add_argument("app_name", help="创建app的名称")
def execute(self, args):
app_name = args.app_name
print(f"app:{app_name},创建成功!")
if __name__ == '__main__':
ManagementTools().execute()
使用说明
添加命令
查看可执行命令
使用help命令查看可执行命令的帮助说明
执行命令,会执行execute方法中实现的功能