Python_argparse_读取命令行参数

一、模块初解

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方法中实现的功能

 

posted @ 2023-01-27 14:36  码上测  阅读(349)  评论(0编辑  收藏  举报