python argparsemutual_exclusive_group 和 add_argument_group 在父处理器中?

Pau*_* T. 5 python argparse

我不确定我是否发现了 argparse 错误,或者我是否很迟钝。我研究了#45602511,这就是我发现它在顶级案例中“起作用”的方式。

我试图使用 argument_group 来分离一些格式选项(它们恰好是互斥的)。如果事情位于解析器结构的顶层,我可以将 a 嵌套mutually_exclusive_group在 an 下argument_group,然后得到我期望的帮助行为:

以下代码在 Python 3.6.2 中运行良好:

import argparse

parser = argparse.ArgumentParser()
commands = parser.add_subparsers()
hit = commands.add_parser('hit')
miss = commands.add_parser('miss')

parser.add_argument('--summary', action='store_true', help='summarize information')
parser.add_argument('--verbose', action='store_true', help='tell us more')

output_format = parser.add_argument_group("Output format")
styles = output_format.add_mutually_exclusive_group()
styles.add_argument('--plain', dest='style')
styles.add_argument('--green', dest='style')
styles.add_argument('--blue', dest='style')

print(parser.parse_args(['-h']))
Run Code Online (Sandbox Code Playgroud)

生成以下输出:

usage: baz.py [-h] [--summary] [--verbose]
              [--plain STYLE | --green STYLE | --blue STYLE]
              {hit,miss} ...

positional arguments:
  {hit,miss}

optional arguments:
  -h, --help     show this help message and exit
  --summary      summarize information
  --verbose      tell us more

Output format:
  --plain STYLE
  --green STYLE
  --blue STYLE
Run Code Online (Sandbox Code Playgroud)

但是,我实际上需要子解析器的帮助代码,而不是在顶层,所以我的代码实际上看起来像这样,并且 argparse 忽略 argument_group 嵌套:

global_options = argparse.ArgumentParser(add_help=False)
global_options.add_argument('--summary', action='store_true', help='summarize information')
global_options.add_argument('--verbose', action='store_true', help='tell us more')

output_format = global_options.add_argument_group("Output format", "ways to foo")
styles = output_format.add_mutually_exclusive_group()
styles.add_argument('--plain', dest='style')
styles.add_argument('--green', dest='style')
styles.add_argument('--blue', dest='style')

parser = argparse.ArgumentParser()
commands = parser.add_subparsers()
hit = commands.add_parser('hit', parents=[global_options])
miss = commands.add_parser('miss', parents=[global_options])

print(parser.parse_args(['hit', '-h']))
Run Code Online (Sandbox Code Playgroud)

生产:

usage: bar.py hit [-h] [--summary] [--verbose]
                  [--plain STYLE | --green STYLE | --blue STYLE]

optional arguments:
  -h, --help     show this help message and exit
  --summary      summarize information
  --verbose      tell us more
  --plain STYLE
  --green STYLE
  --blue STYLE

Output format:
  ways to foo
Run Code Online (Sandbox Code Playgroud)

我做错了什么,还是 argparse 坏了?

hpa*_*ulj 4

a 中嵌套互斥组的问题parents已在几个错误/问题中提出。

http://bugs.python.org/issue25882,(argparse help error: arguments created by add_mutually_exclusive_group() are shown outside their parent group created by add_argument_group())

和

http://bugs.python.org/issue16807,(argparse group nesting lost on inheritance)

在参数组中嵌套互斥组是可行的,但没有记录。但单元测试文件中有一个这样的例子,http://bugs.python.org/issue17218,(support title and description in argparse add_mutually_exclusive_group)

从 a 复制组和操作parents是由parser._add_container_actions方法处理的。该parents机制对于简单的解析器来说工作得很好,但它没有被大量使用,也不够健壮。


示例子解析器创建函数

def make_subparser(commands, name):
  sub = commands.add_parser(name)
  sub.add_argument('--summary', action='store_true', help='summarize information')
  sub.add_argument('--verbose', action='store_true', help='tell us more')
  output_format = sub.add_argument_group("Output format", "ways to foo")
  styles = output_format.add_mutually_exclusive_group()
  styles.add_argument('--plain', dest='style')
  styles.add_argument('--green', dest='style')
  styles.add_argument('--blue', dest='style')
return sub

parser = argparse.ArgumentParser()
commands = parser.add_subparsers()
hit = make_subparser(commands,'hit')
miss = make_subparser(commands 'miss')
Run Code Online (Sandbox Code Playgroud)