【Python开发】学习笔记 - 命令行参数解析

127 阅读3分钟

前言

之前用 Shell 开发脚本时,为了实现复杂参数的解析,还特意花时间搞了个 ShellScriptTpl

但是了解了 Python 命令行脚本开发后,由衷的感到”真香“。。

命令行参数解析 - argparse

如下为《 argparse --- 命令行选项、参数和子命令解析器》的笔记,详情可查阅文档

#!/usr/bin/env python3

# 0701_cmd_argparse.py
#
# 详见:
# https://www.jb51.net/article/238852.htm
# https://docs.python.org/zh-cn/3/howto/argparse.html
# https://docs.python.org/zh-cn/3/library/argparse.html

import argparse, textwrap


# sub-command functions
def foo(args):
    print(args.x * args.y)


def bar(args):
    print('((%s))' % args.z)


#######################################################################################################################

parser = argparse.ArgumentParser(
    formatter_class=argparse.RawDescriptionHelpFormatter,
    # prog='命令名',
    prefix_chars='-+',
    description=textwrap.dedent('''
    Python 命令行脚本参数使用示例
    1. 说明一:xxxx
    2. 说明二:xxxx
    '''),
    epilog='我是使用说明的底部文字'
)  # 可通过`parser.print_help()`手动打印使用说明

# 位置参数
parser.add_argument('action', nargs='?', help='位置参数说明...')  # 指定可选值

# 选项参数:互斥的
group = parser.add_mutually_exclusive_group()  # 若指定 `required=True` 表示在互斥组中至少有一个参数是需要的
group.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='显示详细日志')
group.add_argument('-q', '--quiet', dest='quiet', action='store_true', help='不显示任何日志')

# 选项参数
parser.add_argument('-d', '--debug', dest='debug', action='store_true', help='启用调试模式')
parser.add_argument('-n', '--name', dest='name', default='默认值', help='选项说明...,默认为"%(default)s"')  # 指定 str 默认值
parser.add_argument('-l', '--length', dest='length', type=int, default=0, help='选项说明...')  # 指定 int 默认值
parser.add_argument('-m', '--mode', type=int, choices=[0, 1, 2], help='选项说明...')  # 指定 枚举值
parser.add_argument('-c', '--count', action='count', default=0, help='选项说明...')  # -c、-ccccc 计数
parser.add_argument('-f', '--files', nargs='+', help='选项说明...')  # 列表值: -f aa bb cc
parser.add_argument('-F', '--Files', action="extend", nargs='+', help='选项说明...')  # 存储列表值: -F aa bb cc -F dd ee
parser.add_argument('-p', '--path', action='store_const', const='指定路径', help='选项说明...')  # 指定action为'存储 指定常量'
parser.add_argument('-a', '--appends', action='append', help='选项说明...')  # 存储列表,如:-a 1 -a 2 -a 3
parser.add_argument('+t', dest='times', action='count', help='选项说明...')  # 使用自定义扩增的字符前缀'+',如:+a
parser.add_argument('-V', '--version', action='version', version='%(prog)s 1.0')  # 版本号
parser.add_argument('-r', '--required', required=True, help='必要选项,选项说明...')  # 必须选项参数
parser.add_argument('--foo', help=argparse.SUPPRESS)  # 静默特定选项的帮助

# 选项参数:追加常量到指定列表,如: --str --int
parser.add_argument('--str', dest='types', action='append_const', const='str', help='选项说明...')
parser.add_argument('--int', dest='types', action='append_const', const='int', help='选项说明...')

# 参数组
group = parser.add_argument_group('group A', 'group A description')
group.add_argument('gbar', nargs='?', help='bar help')
group.add_argument('--gfoo', nargs='?', help='foo help')

# 子命令
subparsers = parser.add_subparsers(title='subcommands', description='valid subcommands', help='additional help')

# create the parser for the "a" command
parser_a = subparsers.add_parser('a', help='a help')
parser_a.add_argument('bar', type=int, help='bar help')
# create the parser for the "b" command
parser_b = subparsers.add_parser('b', help='b help')
parser_b.add_argument('--baz', choices='XYZ', help='baz help')
# 使用附加的 aliases 参数
parser_c = subparsers.add_parser('checkout', aliases=['co'])
parser_c.add_argument('pcccc', help='pcccc help')
# create the parser for the "foo" command
parser_foo = subparsers.add_parser('foo')
parser_foo.add_argument('-x', type=int, default=1)
parser_foo.add_argument('y', type=float)
parser_foo.set_defaults(func=foo)
# create the parser for the "bar" command
parser_bar = subparsers.add_parser('bar')
parser_bar.add_argument('z')
parser_bar.set_defaults(func=bar)

# 默认值:允许加入一些无须任何命令行检查的额外属性
parser.set_defaults(default_int=42, default_str='badger')

# 解析
args = parser.parse_args()
print(f' 参数解析结果 '.center(120, '='))
print(f'args = {args}')
print(f'type(args) = {type(args)}')
print(f'parser.parse_args() = {parser.parse_args()}')
print(f'vars(parser.parse_args()) = {vars(parser.parse_args())}')

print(f' 使用 '.center(120, '='))
print(f'action = {args.action} —— {type(args.action)}')
print(f'debug = {args.debug} —— {type(args.debug)}')
print(f'verbose = {args.verbose} —— {type(args.verbose)}')
print(f'name = {args.name} —— {type(args.name)}')
print(f'length = {args.length} —— {type(args.length)}')
print(f'count = {args.count} —— {type(args.count)}')
print(f'mode = {args.mode} —— {type(args.mode)}')
print(f'files = {args.files} —— {type(args.files)}')
print(f'Files = {args.Files} —— {type(args.Files)}')
print(f'path = {args.path} —— {type(args.path)}')
print(f'appends = {args.appends} —— {type(args.appends)}')
print(f'times = {args.times} —— {type(args.times)}')
print(f'types = {args.types} —— {type(args.types)}')
print(f'required = {args.required} —— {type(args.required)}')
print()
print(f'default_int = {args.default_int} —— {type(args.default_int)}')
print(f'default_str = {args.default_str} —— {type(args.default_str)}')
print(f'default_str = {parser.get_default("default_str")}')  # 获取一个命名空间属性的默认值

#######################################################################################################################
# $ python3 0701_cmd_argparse.py -r a
# ======================================================== 参数解析结果 ========================================================
# args = Namespace(action=None, verbose=False, quiet=False, debug=False, name='默认值', length=0, mode=None, count=0, files=None, Files=None, path=None, appends=None, times=None, required='a', foo=None, types=None, gbar=None, gfoo=None, default_int=42, default_str='badger')
# type(args) = <class 'argparse.Namespace'>
# parser.parse_args() = Namespace(action=None, verbose=False, quiet=False, debug=False, name='默认值', length=0, mode=None, count=0, files=None, Files=None, path=None, appends=None, times=None, required='a', foo=None, types=None, gbar=None, gfoo=None, default_int=42, default_str='badger')
# vars(parser.parse_args()) = {'action': None, 'verbose': False, 'quiet': False, 'debug': False, 'name': '默认值', 'length': 0, 'mode': None, 'count': 0, 'files': None, 'Files': None, 'path': None, 'appends': None, 'times': None, 'required': 'a', 'foo': None, 'types': None, 'gbar': None, 'gfoo': None, 'default_int': 42, 'default_str': 'badger'}
# ========================================================== 使用 ==========================================================
# action = None —— <class 'NoneType'>
# debug = False —— <class 'bool'>
# verbose = False —— <class 'bool'>
# name = 默认值 —— <class 'str'>
# length = 0 —— <class 'int'>
# count = 0 —— <class 'int'>
# mode = None —— <class 'NoneType'>
# files = None —— <class 'NoneType'>
# Files = None —— <class 'NoneType'>
# path = None —— <class 'NoneType'>
# appends = None —— <class 'NoneType'>
# times = None —— <class 'NoneType'>
# types = None —— <class 'NoneType'>
# required = a —— <class 'str'>
#
# default_int = 42 —— <class 'int'>
# default_str = badger —— <class 'str'>
# default_str = badger