使用parent_parser进行子分析

时间:2016-03-18 22:52:13

标签: python python-3.x argparse

来自my previous question接受的答案的建议,以及this问题,我尝试过:

parser = argparse.ArgumentParser(description="output parser")
line_parser = argparse.ArgumentParser(add_help=False)
line_parser.add_argument("-N", help="Showing first N line",
                    metavar='integer', type=int)
line_parser.add_argument("-n", help="Showing last n line",
                    metavar='integer', type=int)
parser.add_argument("opt", help="grep string from file",
                    nargs=2, metavar=("str", "file"))
subp = parser.add_subparsers()
pscf = subp.add_parser("scf", help="show convergence", parents=[line_parser])#,
pkp = subp.add_parser("kpoint", help="show kpoints")
pnb = subp.add_parser("nband", help="show number of bands")
pmd = subp.add_parser("md", help="Create xyz file for each ionic step for"
                    " visualization")#, action='store_true')
pfrc = subp.add_parser("force", help="See which atom has maximum force")
# parser.add_argument("--xsf", help="Create xsf file for md(default is xyz)"
                    # " visualization", action='store_true')
args = parser.parse_args()

这是错误的:

python3 vasp.py --help
Traceback (most recent call last):
  File "vasp.py", line 27, in <module>
    args = parser.parse_args()
  File "/usr/lib64/python3.4/argparse.py", line 1728, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/usr/lib64/python3.4/argparse.py", line 1760, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/usr/lib64/python3.4/argparse.py", line 1966, in _parse_known_args
    start_index = consume_optional(start_index)
  File "/usr/lib64/python3.4/argparse.py", line 1906, in consume_optional
    take_action(action, args, option_string)
  File "/usr/lib64/python3.4/argparse.py", line 1834, in take_action
    action(self, namespace, argument_values, option_string)
  File "/usr/lib64/python3.4/argparse.py", line 1016, in __call__
    parser.print_help()
  File "/usr/lib64/python3.4/argparse.py", line 2359, in print_help
    self._print_message(self.format_help(), file)
  File "/usr/lib64/python3.4/argparse.py", line 2336, in format_help
    formatter.add_arguments(action_group._group_actions)
  File "/usr/lib64/python3.4/argparse.py", line 272, in add_arguments
    self.add_argument(action)
  File "/usr/lib64/python3.4/argparse.py", line 257, in add_argument
    invocations = [get_invocation(action)]
  File "/usr/lib64/python3.4/argparse.py", line 535, in _format_action_invocation
    metavar, = self._metavar_formatter(action, default)(1)
ValueError: too many values to unpack (expected 1)

如果我删除了所有line_parser,那么它可以正常工作。但我需要它们,因为-N和-n将用于多个选项,但这里没有显示。

我已阅读this但尚未设法同化。

2 个答案:

答案 0 :(得分:0)

该例外与line_parser无关,但参数&#39; metavar&#39;第8行。将元组更改为列表将使您的代码正常工作。

parser.add_argument("opt", help="grep string from file",
                    nargs=2, metavar=["str", "file"])

答案 1 :(得分:0)

我同意,这不是SELECT gameId AS gi, COUNT(gameId) AS counted FROM player GROUP BY gameId ORDER BY counted DESC LIMIT 1; parents问题,而是subparsernargs问题。有一个相关的Python错误/问题

http://bugs.python.org/issue14074; metavar

几年前我提出了一个补丁,但是argparse问题积压很多,所以没有采取任何行动。

如果argparse allows nargs>1 for positional arguments but doesn't allow metavar to be a tuple更改为opt

--opt

然后帮助是:

parser.add_argument("--opt", help="grep string from file",
                nargs=2, metavar=("str", "file"))

我认为这就是目的。

将元变量更改为列表会产生

1949:~/mypy$ python stack36095543.py -h
usage: stack36095543.py [-h] [--opt str file] {scf,kpoint,nband,md,force} ...

output parser

positional arguments:
  {scf,kpoint,nband,md,force}
    scf                 show convergence
  ...

optional arguments:
  -h, --help            show this help message and exit
  --opt str file        grep string from file

我不认为是预期用途。

根据文件:

  

为metavar提供元组为每个参数指定不同的显示:

我建议使用usage: stack36095543.py [-h] [--opt ['str', 'file'] ['str', 'file']] {scf,kpoint,nband,md,force} ... 参数。一,它使这个metavar显示正确。其中两个,--opt与次级分析师不能很好地发挥作用。 subparser也是一种位置参数(伪装)。我认为将其他主要解析器参数定义为'optionals'

更安全

注意,如果我制作positionals --opt,则用法如下:

required=True

在这种情况下,区分标志和参数有点困难。 usage: stack36095543.py [-h] --opt str file {scf,kpoint,nband,md,force} ... 使用大写字母表示默认的argparse元变量。很明显是否可以使用:

optionals

另一种可能性是用2个位置替换 usage: stack36095543.py [-h] --opt STR FILE {scf,kpoint,nband,md,force} ... 参数

nargs=2
制造

parser.add_argument("grep",metavar='STR')
parser.add_argument("file",metavar='FILE')

usage: stack36095543.py [-h] STR FILE {scf,kpoint,nband,md,force} ... positional(或*,+)最适用于所有值都相同的情况 - 列表中的值。在它们代表不同的东西的地方,使用单独的论证更有意义。

在进一步测试中,我发现您的代码处理使用情况很好。 nargs=2生成:

parser.print_usage()

格式化帮助行时会产生错误。一行看起来像:

usage: stack36095543.py [-h] str file {scf,kpoint,nband,md,force} ...

根据我在bug /问题上的帖子,这样的metavar在显示错误信息时也会出现问题。