如果我有一个在多个参数之间共享的有效选项字符串列表,则该列表将写入帮助字符串中的多个位置。让它更难阅读:
def main():
elements = ['a', 'b', 'c', 'd', 'e', 'f']
parser = argparse.ArgumentParser()
parser.add_argument(
'-i',
nargs='*',
choices=elements,
default=elements,
help='Space separated list of case sensitive element names.')
parser.add_argument(
'-e',
nargs='*',
choices=elements,
default=[],
help='Space separated list of case sensitive element names to '
'exclude from processing')
parser.parse_args()
使用命令行参数--help
运行上述函数时,它显示:
usage: arguments.py [-h] [-i [{a,b,c,d,e,f} [{a,b,c,d,e,f} ...]]]
[-e [{a,b,c,d,e,f} [{a,b,c,d,e,f} ...]]]
optional arguments:
-h, --help show this help message and exit
-i [{a,b,c,d,e,f} [{a,b,c,d,e,f} ...]]
Space separated list of case sensitive element names.
-e [{a,b,c,d,e,f} [{a,b,c,d,e,f} ...]]
Space separated list of case sensitive element names
to exclude from processing
如果可以定义选项列表名称,并且在帮助输出中在多个位置写入选项列表名称并最后定义它,那将是很好的。理论上它会像这样工作:
def main_optionlist():
elements = ['a', 'b', 'c', 'd', 'e', 'f']
# Two instances of OptionList are equal if and only if they
# have the same name (ALFA in this case)
ol = OptionList('ALFA', elements)
parser = argparse.ArgumentParser()
parser.add_argument(
'-i',
nargs='*',
choices=ol,
default=ol,
help='Space separated list of case sensitive element names.')
parser.add_argument(
'-e',
nargs='*',
choices=ol,
default=[],
help='Space separated list of case sensitive element names to '
'exclude from processing')
parser.parse_args()
使用命令行参数--help
运行上述函数时,它会显示类似于:
usage: arguments.py [-h] [-i [ALFA [ALFA ...]]]
[-e [ALFA [ALFA ...]]]
optional arguments:
-h, --help show this help message and exit
-i [ALFA [ALFA ...]]
Space separated list of case sensitive element names.
-e [ALFA [ALFA ...]]
Space separated list of case sensitive element names
to exclude from processing
sets in optional arguments:
ALFA {a,b,c,d,e,f}
我需要:
所以我问:
我曾尝试查看argparse的源代码,但由于这种修改感觉非常先进,我不知道该如何开始。
答案 0 :(得分:18)
我的回答并不是试图扩展argparse,而是使用argparse的可用选项......这样可以解决你的情况吗?
import argparse
import textwrap
def main():
elements = ['a', 'b', 'c', 'd', 'e', 'f']
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog = textwrap.dedent('''\
sets in optional arguments:
ALFA\t\t{a,b,c,d,e,f}"
'''))
parser.add_argument(
'-i',
nargs='*',
choices=elements,
default=elements,
metavar="ALFA",
help='Space separated list of case sensitive element names.')
parser.add_argument(
'-e',
nargs='*',
choices=elements,
default=[],
metavar="ALFA",
help='Space separated list of case sensitive element names to '
'exclude from processing')
parser.parse_args()
usage: test.py [-h] [-i [ALFA [ALFA ...]]] [-e [ALFA [ALFA ...]]]
optional arguments:
-h, --help show this help message and exit
-i [ALFA [ALFA ...]] Space separated list of case sensitive element names.
-e [ALFA [ALFA ...]] Space separated list of case sensitive element names
to exclude from processing
sets in optional arguments:
ALFA {a,b,c,d,e,f}"
这种方法的好处在于,您可以随意为每个标志命名metavar,并且您可以手动设置epilog的格式以反映任何格式描述。不需要子类化。
答案 1 :(得分:10)
根据现在已删除的赏金捐赠者的请求,与其他答案形成鲜明对比的完全通用的解决方案:
import argparse
from operator import itemgetter
class OptionListGroup(object):
class GroupAction(object):
def __init__(self, left, right):
self.help = right
self.option_strings = [left]
self.nargs = 0
def __init__(self, lists):
self.description = None
self.title = "referenced sets"
self._group_actions = [self.GroupAction(name, self.format_list(lst))
for name, lst in sorted(lists)]
def format_list(self, lst):
return '{%s}' % ', '.join(map(str, lst))
class MyArgParser(argparse.ArgumentParser):
def __init__(self, *args, **kwargs):
self._option_lists = {}
super(MyArgParser, self).__init__(*args, **kwargs)
def parse_args(self, *args, **kw):
self._action_groups.append(OptionListGroup(self._option_lists.values()))
return super(MyArgParser, self).parse_args(*args, **kw)
def add_option_list(self, name, lst):
if name in map(itemgetter(0), self._option_lists.values()):
raise ValueError, "Name already existing"
self._option_lists[id(lst)] = (name, lst)
def add_argument(self, *args, **kw):
name_list = self._option_lists.get(id(kw.get('choices')))
if name_list:
kw['metavar'] = name_list[0]
return super(MyArgParser, self).add_argument(*args, **kw)
使用示例:
alfa = ['a', 'b', 'c', 'd', 'e', 'f']
num = [1, 2, 3]
parser = MyArgParser()
parser.add_option_list('ALFA', alfa)
parser.add_option_list('NUM', num)
parser.add_argument(
'-a',
nargs='*',
choices=alfa,
default=alfa,
help='Characters (defaults to include all)')
parser.add_argument(
'-e',
nargs='*',
choices=num,
default=[],
help='Digits (defaults to exclude all)')
parser.parse_args()
帮助输出:
usage: argparse-optionlist.py [-h] [-a [ALFA [ALFA ...]]]
[-e [NUM [NUM ...]]]
optional arguments:
-h, --help show this help message and exit
-a [ALFA [ALFA ...]] Characters (defaults to include all)
-e [NUM [NUM ...]] Digits (defaults to exclude all)
referenced sets:
ALFA {a, b, c, d, e, f}
NUM {1, 2, 3}
答案 2 :(得分:1)
我不完全确定我明白你想要什么。 。 。,类似于以下内容:
import argparse
elements = ['a', 'b', 'c', 'd', 'e', 'f']
class myparser(argparse.ArgumentParser):
def add_argument(self,*args,**kwargs):
choice=kwargs.get('choices',None)
if(choice is elements):
kwargs['metavar']='ALFA'
return argparse.ArgumentParser.add_argument(self,*args,**kwargs)
def main():
epilog="""sets in optional arguments:
ALFA %s"""%(str(elements).replace('[','{').replace(']','}'))
parser = myparser(epilog=epilog,formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument(
'-i',
nargs='*',
choices=elements,
default=elements,
help='Space separated list of case sensitive element names.')
parser.add_argument(
'-e',
nargs='*',
choices=elements,
default=[],
help='Space separated list of case sensitive element names to '
'exclude from processing')
parser.parse_args()
main()
或者,您可以直接使用metavar
关键字。格式化程序的更改是使epilog以您想要的方式显示。一般来说,我建议不要使用它。
修改强>
根据您的python版本,您可能有RawDescriptionHelpFormatter
可用,我建议您使用此问题。