首页 > 解决方案 > 覆盖 argparse 参数与父解析器有奇怪的交互

问题描述

我正在使用 ArgumentParser.add_subparsers() 设置一系列子解析器,其中有一个通用父解析器用于我希望在子命令的任一侧都可用的全局选项。例如,我想command --foo subcommand等价于command subcommand --foo. 最简单的方法是使用公共选项创建一个单独的 argparse.ArgumentParser,并将其传递parents=[parent_parser]给主解析器和子解析器。这部分有效。

当我想覆盖其中一个子系统的父解析器中的参数之一时,就会出现问题。有一个我想强制关闭的标志(很容易完成),但更重要的是我希望subcommand -h信息清楚地表明此选项已禁用。

文档说我可以conflict_handler='resolve'在构造子解析器时进行设置,然后它会覆盖冲突的参数,我可以这样做。但是,当它这样做时,它似乎以某种方式覆盖action了父解析器的 ,而不是default.

在下面的代码中,如果您以argparse_fun.pyor运行它,argparse_fun.py -f则输出为Namespace(foo=True). 如果您将其作为argparse_fun.py aor运行,argparse_fun.py a -f则输出为Namespace(foo=False).

我错过了什么吗?我发现错误了吗?有没有办法避免这个问题?

演示该问题的最小可行代码:

#!python3
import argparse

parent_parser = argparse.ArgumentParser(add_help=False)
parent_parser.add_argument('-f', '--foo', action='store_true', help='Parent foo')

parser = argparse.ArgumentParser(parents=[parent_parser])
subparsers = parser.add_subparsers(title='sub parsers')

subparser_a = subparsers.add_parser('a', parents=[parent_parser], conflict_handler='resolve')
subparser_a.add_argument('-f', '--foo', default=False, action='store_false', help='disabled for a')

print(parser.parse_args())

的输出argparse_fun.py似乎暗示它部分覆盖了父级,因为它-h仍然知道Parent foo存在但没有显示任何与之关联的参数:

usage: argparse_fun.py [-h]  {a} ...

optional arguments:
  -h, --help  show this help message and exit
  foo         Parent foo

sub parsers:
  {a}

如果你仔细看,你会注意到参数[-h]{a}参数之间有一个空格,并且Parent foo没有任何与之关联的标志,但主解析器仍然知道它有一个参数。很奇怪。

标签: python-3.xargparse

解决方案


推荐阅读