gpt4 book ai didi

python - argparse - 组合父解析器、子解析器和默认值

转载 作者:太空狗 更新时间:2023-10-29 17:47:17 27 4
gpt4 key购买 nike

我想在脚本中定义不同的子解析器,它们都从一个共同的父级继承选项,但具有不同的默认值。但是,它没有按预期工作。

这是我做的:

import argparse

# this is the top level parser
parser = argparse.ArgumentParser(description='bla bla')

# this serves as a parent parser
base_parser = argparse.ArgumentParser(add_help=False)
base_parser.add_argument('-n', help='number', type=int)


# subparsers
subparsers = parser.add_subparsers()
subparser1= subparsers.add_parser('a', help='subparser 1',
parents=[base_parser])
subparser1.set_defaults(n=50)
subparser2 = subparsers.add_parser('b', help='subparser 2',
parents=[base_parser])
subparser2.set_defaults(n=20)

args = parser.parse_args()
print args

当我从命令行运行脚本时,这是我得到的:

$ python subparse.py b
Namespace(n=20)

$ python subparse.py a
Namespace(n=20)

显然,第二个 set_defaults 覆盖了父级中的第一个。由于 argparse 文档(非常详细)中没有关于它的任何内容,我认为这可能是一个错误。

是否有一些简单的解决方案?之后我可以检查 args 变量并将 None 值替换为每个子解析器的预期默认值,但这是我期望 argparse 为我做的。

顺便说一句,这是 Python 2.7。

最佳答案

set_defaults 遍历解析器的 Action ,并设置每个 default 属性:

   def set_defaults(self, **kwargs):
...
for action in self._actions:
if action.dest in kwargs:
action.default = kwargs[action.dest]

您的 -n 参数(一个 action 对象)是在您定义 base_parser 时创建的。当使用 parents 创建每个子解析器时,该操作将添加到每个子解析器的 ._actions 列表中。它没有定义新的 Action ;它只是复制指针。

因此,当您在 subparser2 上使用 set_defaults 时,您修改了此共享操作的 default

此操作可能是 subparser1._action 列表中的第二项(h 是第一项)。

 subparser1._actions[1].dest  # 'n'
subparser1._actions[1] is subparser2._actions[1] # true

如果第二条语句为 True,则意味着相同的 action 出现在两个列表中。

如果您为每个子解析器单独定义了 -n,您将看不到它。他们会有不同的 Action 对象。

我是根据我对代码的了解来工作的,而不是文档中的任何内容。最近在Cause Python's argparse to execute action for default中指出该文档没有说明 add_argument 返回一个 Action 对象。这些对象是代码组织的重要组成部分,但在文档中并没有得到太多关注。


如果使用“解决”冲突处理程序,则通过引用复制父操作也会产生问题,并且需要重用父操作。这个问题是在

argparse conflict resolver for options in subcommands turns keyword argument into positional argument

和 Python 错误问题:

http://bugs.python.org/issue22401

对于这个问题和那个问题,一个可能的解决方案是(可选)复制操作,而不是共享引用。这样,option_stringsdefaults 可以在子级中修改,而不会影响父级。

关于python - argparse - 组合父解析器、子解析器和默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24666197/

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