argparse的增强:额外的操作、子parser别名、智能格式化程序、基于decorator的包装器
ruamel.std.argparse的Python项目详细描述
此包在两个级别上提供argparse的扩展:
- 基本argparse扩展:默认子parser,子parser别名 2.x
- 可以为add_参数指定的其他操作
- 允许组合默认值的智能格式化程序有助于格式化 和原始描述
- 使用decorators的argparse包装器
基本argparse的扩展
插入以下内容以便能够在中指定aliases 2.6和2.7中的子类定义:
from __future__ import print_function import sys from ruamel.std.argparse import ArgumentParser, SubParsersAction parser = ArgumentParser() if sys.version_info < (3,): # add aliases support parser.register('action', 'parsers', SubParsersAction) subparsers = parser.add_subparsers() checkout = subparsers.add_parser('checkout', aliases=['co']) checkout.add_argument('foo') args = parser.parse_args(['co', 'bar']) print(args)
结果:
Namespace(foo='bar')
其他操作
倒计时
上下计数:
from __future__ import print_function from ruamel.std.argparse import CountAction import argparse parser = argparse.ArgumentParser() parser.add_argument('--verbose', '-v', action=CountAction, const=1, nargs=0) parser.add_argument('--quiet', '-q', action=CountAction, dest='verbose', const=-1, nargs=0) print(parser.parse_args("--verbose -v -q".split()))
结果:
Namespace(verbose=1)
SplitAppend
在“,”上拆分后追加。跑步:
from __future__ import print_function from ruamel.std.argparse import SplitAppendAction import argparse parser = argparse.ArgumentParser() parser.add_argument('-d', action=SplitAppendAction) print(parser.parse_args("-d ab -d cd -d kl -d mn".split())) print(parser.parse_args("-d ab,cd,kl,mn".split())) print(parser.parse_args("-d ab,cd -d kl,mn".split()))
结果:
Namespace(d=['ab', 'cd', 'kl', 'mn']) Namespace(d=['ab', 'cd', 'kl', 'mn']) Namespace(d=['ab', 'cd', 'kl', 'mn'])
checksinglestoreaction
如果多次调用同一选项,请投诉:
from __future__ import print_function from ruamel.std.argparse import CheckSingleStoreAction import argparse parser = argparse.ArgumentParser() parser.add_argument('--check', '-c', action=CheckSingleStoreAction, const=1, nargs=0) print(parser.parse_args("--check -c".split()))
结果:
WARNING: previous optional argument "-c []" overwritten by "-c []" Namespace(check=[])
智能格式
在标准argparse中只能指定一个格式化程序,因此不能 两者都有预先格式化的描述。使用 rawdescriptionhelpformatter,以及 ArgumentDefaultShelpFormatter。
SmartFormatter是argparse.HelpFormatter和 默认使用普通格式化程序。帮助文本可以标记在 开始更改格式:
- "R|.."原始格式,即不换行填写,观察员换行
- "*|.."设置密码帮助格式,不回显默认密码
- "D|.."将默认值添加到all条目(这就是为什么有*| 很重要)
版本字符串使用分割线格式化,并保留任何 版本字符串中的换行符。
from __future__ import print_function from ruamel.std.argparse import SmartFormatter import argparse def exit(self, *args, **kw): pass argparse.ArgumentParser.exit = exit # the 'D|....' in the second pass triggers generating defaults for all entries, # while being smart about which one already have a %(default)s for index, log_s in enumerate(['log to file', 'D|log to file']): parser = argparse.ArgumentParser(formatter_class=SmartFormatter) parser.add_argument('--log', default='abc.log', help=log_s) parser.add_argument('--username', help='username to login with (default: %(default)s)') parser.add_argument('--password', help='*|password to use for login') parser.add_argument('--recursive', '-r', action='store_true', help="R|recurse into subdirectories \nto find files") parser.set_defaults(username='anthon', password="test123") if index > 0: print('--------------------------------------\n') parser.parse_args(["--help"])
结果:
usage: smartformatter.py [-h] [--log LOG] [--username USERNAME] [--password PASSWORD] [--recursive] optional arguments: -h, --help show this help message and exit --log LOG log to file --username USERNAME username to login with (default: anthon) --password PASSWORD password to use for login --recursive, -r recurse into subdirectories to find files -------------------------------------- usage: smartformatter.py [-h] [--log LOG] [--username USERNAME] [--password PASSWORD] [--recursive] optional arguments: -h, --help show this help message and exit --log LOG log to file (default: abc.log) --username USERNAME username to login with (default: anthon) --password PASSWORD password to use for login (default: *******) --recursive, -r recurse into subdirectories to find files (default: False)
包装argparse
当使用argparse和subparser时,每个子parser都有自己的 可以调用的函数(使用.set_defaults(func=function), 有很多重复的代码。
ProgramBase类提供了一个替代项,它应该是 子类和sub_parser、option和version 可应用于该子类的方法的修饰符。
典型的用例是:
from __future__ import print_function import sys import os from ruamel.std.argparse import ProgramBase, option, sub_parser, version, \ SmartFormatter class TestCmd(ProgramBase): def __init__(self): super(TestCmd, self).__init__( formatter_class=SmartFormatter ) # you can put these on __init__, but subclassing TestCmd # will cause that to break @option('--quiet', '-q', help='suppress verbosity', action='store_true', global_option=True) @version('version: 1.2.3') def _pb_init(self): # special name for which attribs are included in help pass def run(self): if self._args.func: return self._args.func() def parse_args(self, *args): self._parse_args(*args) @sub_parser(help='specific help for readit') @option('--name', default='abc') def readit(self): print('calling readit') @sub_parser('writeit', help='help for writeit') @option('--target') def other_name(self): print('calling writeit') n = TestCmd() n.parse_args(['--help']) n.run()
输出:
usage: testcmd.py [-h] [--quiet] [--version] {readit,writeit} ... positional arguments: {readit,writeit} readit specific help for readit writeit help for writeit optional arguments: -h, --help show this help message and exit --quiet, -q suppress verbosity --version show program's version number and exit
默认情况下,方法名是子解析器的名称。这可能是 通过向sub_parser提供非关键字参数而重写。这个 关键字参数传递给add_parser方法。
option用作add_argument。如果option被加上 不是子解析器的方法,这样的选项将是全局的 选择。当 调用脚本。通常,使用 一个global_option=True关键字参数。这确保了 选项也会添加到所有子解析器中。这样你就可以 同时调用prog --quiet writeit和prog writeit --quiet)。 您可以将这些选项分配给__init__,但在进行子分类时 TestCmd这将导致问题。因此,最好是pu 如果子类化可能 发生了。
应注意访问TestCmd上的所有属性 在扫描子分析器期间。尤其是任何属性方法 将被访问并执行其代码。
默认命令
如果希望将特定的子语法分析器作为默认调用,则 可以使用:
self._parse_args(default_sub_parser='show')
在一个名为 pass相同:
pass pass show
所有子命令的帮助
如果为的可选帮助所有参数提供真值 self._parse_args():
self._parse_args(help_all=True)
然后检查命令行中的选项--help-all和全局 打印帮助,然后是每个子解析器的帮助,用虚线分隔 行。
测试
测试是使用tox完成的,它 U型sesvirtualenv和 pytest。