gpt4 book ai didi

python - Argparse:如果子解析器共享父级,则子解析器的选项会覆盖主解析器

转载 作者:太空宇宙 更新时间:2023-11-03 11:16:37 25 4
gpt4 key购买 nike

我将 argparse 与多个子解析器一起使用。我希望我的程序在 args 的任何地方都采用冗长选项,包括子解析器。

from argparse import ArgumentParser
p = ArgumentParser()
p.add_argument('--verbose', '-v', action='count')

sub = p.add_subparsers()
a = sub.add_parser('a')

print(p.parse_args())

默认情况下,如果用于子解析器,主解析器的选项将抛出错误:

$ python tmp.py -v a
Namespace(verbose=1)

$ python tmp.py a -v
usage: tmp.py [-h] [--verbose] {a} ...
tmp.py: error: unrecognized arguments: -v

我研究了父解析器,来自 this answer .

from argparse import ArgumentParser

parent = ArgumentParser(add_help=False)
parent.add_argument('--verbose', '-v', action='count')

main = ArgumentParser(parents=[parent])

sub = main.add_subparsers()
a = sub.add_parser('a', parents=[parent])

print(main.parse_args())

但出于某种原因,没有一个共享标志在主解析器上起作用。

$ python tmp2.py a -vvv
Namespace(verbose=3)
$ python tmp2.py -vvv a
Namespace(verbose=None)

请注意,主解析器肯定有适当的参数,因为当我将其更改为 main = ArgumentParser() 时,我得到了 error: unrecognized arguments: -v。我在这里缺少什么?

最佳答案

首先,一些一般性评论。

主解析器处理输入直到调用子解析器,然后调用子解析器并给出剩余的 argv。完成后,它的 namespace 将合并回主 namespace

parents 机制通过引用从parent 复制操作。因此,您的主解析器和子解析器共享相同的 verbose Action 对象。当子解析器尝试设置不同的默认值或帮助时,这是一个问题。这可能不是问题,但请记住这一点。

即使没有 parents 机制,在 main 和 subparser 之间共享 dest 或选项标志也可能很棘手。是否应该使用子解析器 Action 的默认值?如果两者都用呢?子解析器是否会覆盖主解析器的操作?

最初主要的命名空间被传递给子解析器,它修改并返回。这在一段时间前已更改(如果需要,我可以找到错误/问题)。现在,子解析器以默认的空 namespace 开始,并填充它。然后将这些值合并到主值中。

因此,在您链接的 SO 问题中,请注意较旧的答案。 argparse 从那时起可能已经改变。

我认为您的情况是主解析器和子解析器 verbose 分别计数。当你得到 None 时,你看到的是子解析器的默认值。

_Count_Action__call__ 是:

def __call__(self, parser, namespace, values, option_string=None):
new_count = _ensure_value(namespace, self.dest, 0) + 1
setattr(namespace, self.dest, new_count)

我怀疑在较旧的 argparse 中共享命名空间时,count 会累积,但我无法在不重新创建较旧样式的情况下对其进行测试 subparser Action 类。

https://bugs.python.org/issue15327 - 这里原始开发者建议给两个参数不同的dest。它记录了来自 main 和 sub 的输入。如果需要,您自己的代码随后可以合并结果。

https://bugs.python.org/issue27859 argparse - 子解析器不保留命名空间。在这里,我建议一种重新创建旧样式的方法。

https://bugs.python.org/issue9351 子命令上的 argparse set_defaults 应该覆盖顶级 set_defaults - 这是 2014 年更改命名空间使用的问题。

关于python - Argparse:如果子解析器共享父级,则子解析器的选项会覆盖主解析器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50543820/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com