2016-12-28 60 views
1

我正在为各种子分析器编写一个Python模块的参数分析器。我的目标是有一个分享的内容,其参数的构造函数传递给多个孩子一个说法:Python argparse:获取帮助字符串中的子分析器程序的名称

from argparse import ArgumentParser 
parser = ArgumentParser(prog = 'master') 
parser1 = ArgumentParser(help = None) 
parser1.add_argument('foo', type = int, help = 'Number of times to process %(prog)s') # Line of interest 
parser2 = ArgumentParser(help = None) 
parser2.add_argument('--bar', type = int, default = 0, help = 'Start at this number') 
parser3 = ArgumentParser(help = None) 
parser3.add_argument('--baz', type = str, default = 'DEFAULT', help = 'Init file with this text') 
subparsers = parser.add_subparsers() 
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2]) 
sp2 = subparsers.add_parser('prog2', parents = [parser1, parser3]) 
parser.parse_args('prog1 -h'.split()) 

所需的输出会是这样的

usage: master prog1 [-h] [--bar BAR] foo 

positional arguments: 
    foo   Number of times to process prog1 

optional arguments: 
    -h, --help  show this message and exit 
    --bar   Start at this number 

当我使用这个确切的设置,我得到master prog1代替的帮助字符串中的prog1。我应该在标记为#Line of interest的行中更改哪些内容以获得理想的结果?

回答

0

这不是对您的问题的直接回答,但我会使用Click_作为您正在尝试执行的操作。

Click_在三点:

  1. 命令的任意嵌套
  2. 自动帮助页面生成
  3. 支持在运行时
0

我可以解释是怎么回事子的延迟加载,但可能无法提供解决方案。

简短的回答是,sp1.progusage格式中被用作帮助行中的%(prog)s值。它的设计与usage一致。

===============

sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2]) 

创建一个解析器,并从parents增加了论据。 add_parserclass _SubParsersAction(subparser Action类)的一种方法。而对于解析器prog属性与创建:

 if kwargs.get('prog') is None: 
     kwargs['prog'] = '%s %s' % (self._prog_prefix, name) 

你应该能够看到print(sp1.prog)这个属性(我想到“主PROG1”)。这是在usage行中以及在%(prog)s的任何帮助行中使用的值。

subparsers._prog_prefix源自parser.prog(详见add_subparsers代码)。但你也可以指定一个prog参数:

sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='prog1') 

这应该纠正help行的字符串。但它也会改变字符串usage

你也可以给子分析器明确usage

sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='prog1', usage='master prog1 ...') 

没有做手术的HelpFormatter我不认为你可以更改辅助线prog没有使用也改变它。

并给出parents作品的方式,您不能更改prog1 foo的帮助热线,也不会将其更改为prog2 fooparents通过引用复制操作对象,因此这两个子分析器共享foo操作对象。

你很多人不得不放弃parents的方法,至少对于这个参数,并硬编码的名称。如果您需要将参数添加到多个子分析器中,请编写一个小实用程序函数以实现该功能。 parents机制只是(通常)一种便利,可以节省一些打字/编辑。

===================

这个修改后的脚本将说明我的观点

parser = ArgumentParser(prog = 'master') 

parser1 = ArgumentParser(add_help = False) 
fooarg=parser1.add_argument('foo', type = int, help = 'foo prog: %(prog)s') # Line of interest 
parser2 = ArgumentParser(add_help = False) 
parser2.add_argument('--bar', type = int, default = 0, help = 'Start at this number') 
parser3 = ArgumentParser(add_help = False) 
parser3.add_argument('--baz', type = str, default = 'DEFAULT', help = 'Init file with this text') 

subparsers = parser.add_subparsers(prog='subparsers') 
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='name1') 
sp2 = subparsers.add_parser('prog2', parents = [parser1, parser3]) 

#parser.print_help() 

# fooarg is an Action for both subparsers 
# print(fooarg.help) 
# fooarg.help = 'FOO HELP' 

print('==>sp1 prog:', sp1.prog) 
sp1.print_help() 
print('==>sp2 prog:', sp2.prog) 
sp2.print_help() 

sp1.prog = 'custom' 
sp1.print_help() 

# addition 
fooarg.default = 'default' 
fooarg.metavar = 'META' 
fooarg.help = 'prog: %(prog)s, dest=%(dest)s, nargs=%(nargs)s, type=%(type)s, default=%(default)s' 
sp1.print_help() 

这最后位增加了大量动作的属性帮助。但是prog是唯一来自parser

positional arguments: 
    META  prog: custom, dest=foo, nargs=None, type=int, default=default