argparse子命令选项冲突解决程序将关键字参数转为位置参数

2024-04-19 20:51:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python脚本,它运行两个接受相同选项的子命令--config。我想创建第三个子命令,它可以按顺序一起运行前两个子命令。在

使用argparse,我为每个子命令创建了一个子parser,以及第三个子parser,它的父级是两个子命令。只是想澄清一下:

subcommand1 = subparsers.add_parser('subcommand1')
subcommand1.add_argument('--config', help="The config")

subcommand2 = subparsers.add_parser('subcommand2')
subcommand2.add_argument('--config', help="The config")

wrappercommand = subparsers.add_parser('wrappercommand', 
                                       parents=[subcommand1, subcommand2], 
                                       conflict_handler='resolve')

当我运行wrappercommand或subcommand2时,一切正常。但是,子命令1中断,输出如下:

^{pr2}$

看起来argparse已经将关键字arg(“--config”)转换为位置关键字(“config”)。这是argparse解决冲突选项时的预期行为吗?在


Tags: the命令脚本addconfigparser选项argparse
1条回答
网友
1楼 · 发布于 2024-04-19 20:51:09

我认为你是在把这个冲突处理者推向意想不到的、未经考验的领域。通常,parents是独立的解析器,不被使用。它们只是Actions的一个源。关于-h的冲突用add_help=False处理。在

通过背景:使用默认的conflict_handler(error),在创建wrappercommand子parser时,您将收到错误消息:

argparse.ArgumentError: argument -h/ help: conflicting option string(s): -h,  help

在添加一些add_help=False之后,您仍然可以得到:

^{pr2}$

resolve冲突处理程序将错误消息替换为某种“解决方案”。下面的脚本演示了正在发生的事情。在

resolve处理程序删除了subcommand1操作的option_strings,同时保留了这些操作。实际上,它将两者转化为位置。而且由于help有{},所以它总是运行的。因此,将显示帮助。在

_handle_conflict_resolve的目的是删除第一个参数的证据,以便可以添加新的参数。当冲突是由两个具有相同选项字符串的add_argument命令产生时,这种方法可以很好地工作。但在这里,冲突是由两个家长的“抄袭”行为产生的。但是父操作是通过引用复制的,因此“child”中的更改最终会影响“parent”。在

一些可能的解决方案:

  • 直接将参数添加到wrappercommand。此parents机制只是将父对象的参数添加到子对象。它不会按顺序“运行”父对象。

  • 编写您自己的_handle_conflict_...函数来正确解决冲突。

  • 删除冲突,这样就可以使用parents,而不使用resolve处理程序。


我已经用这个例子提交了一个bug报告 http://bugs.python.org/issue22401

parent1 = argparse.ArgumentParser(add_help=False)
parent1.add_argument(' config')
parent2 = argparse.ArgumentParser(add_help=False)
parent2.add_argument(' config')

parser = argparse.ArgumentParser(parents=[parent1,parent2],
    conflict_handler='resolve')

def foo(parser):
    print [(id(a), a.dest, a.option_strings) for a in parser._actions]

foo(parent1)
foo(parent2)
foo(parser)

产生:

[(3077384012L, 'config', [])]
[(3076863628L, 'config', [' config'])]
[(3076864428L, 'help', ['-h', ' help']), (3076863628L, 'config', [' config'])]

注意,parent1缺少的option_strings,其他2个匹配的idparent1不能再次用作父级或解析器。在


argparse - Combining parent parser, subparsers and default values 另一种情况是,通过引用复制父对象的操作会产生复杂情况(更改默认值)。在

相关问题 更多 >