对子命令中的选项argparse的冲突解析器将关键字参数变为位置参数
我有一个Python脚本,它运行两个接受相同选项--config
的子命令。我想创建第三个子命令,它们可以按顺序一起运行前两个子命令。对子命令中的选项argparse的冲突解析器将关键字参数变为位置参数
使用argparse,我为每个子命令以及第三个子分析器创建了一个子分析器,其父母是两个子命令。只是为了澄清:
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时,一切正常。然而,subcommand1休息,以此为输出:
$ run_command.py subcommand1 --config path_to_config.ini
usage: run_command.py subcommand1 config
optional arguments:
help show this help message and exit
config The config
它看起来像argparse已经变成一个关键字ARG(“--config”)到的位置一(“配置”)。这是在argparse解决冲突选项时的预期行为吗?
我认为你正在将这个冲突处理程序推入无意和未经测试的领域。通常,parents
是独立的解析器,无法使用。他们只是Actions
的来源。有关-h
的冲突使用add_help=False
进行处理。
通过背景:使用默认conflict_handler
(错误)创建wrappercommand
子分析器时,你会得到错误信息:
argparse.ArgumentError: argument -h/--help: conflicting option string(s): -h, --help
,并增加了一些add_help=False
之后,你仍然会得到:
argparse.ArgumentError: argument --config: conflicting option string(s): --config
resolve
冲突处理程序用某种“分辨率”替换错误消息。下面的脚本演示了正在发生的事情。
resolve
处理程序删除了option_strings
为subcommand1
的操作,同时使操作保持原位。实际上它将两者都转化为定位。由于help
有nargs=0
,它总是运行。因此,帮助显示。
_handle_conflict_resolve
的意图是去除第一个参数的证据,所以可以添加新的参数。当冲突由两个add_argument
命令产生并具有相同的选项字符串时,可以正常工作。但是这里的冲突是由两位父母的“复制”行为产生的。但是父母的行为通过引用被复制,所以'孩子'的变化最终影响'父母'。
一些可能的解决方案:
参数添加到
wrappercommand
直接。这个parents
机制只是增加了父母对孩子的争论。它不会“连续”运行父母。编写自己的
_handle_conflict_...
函数来正确解决冲突。删除冲突,因此您可以使用
parents
而不使用resolve
处理程序。
我已经提交给美国这个例子 http://bugs.python.org/issue22401一个bug报告:
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'])]
注意失踪option_strings
为parent1
,并匹配id
其他2. parent1
不能再次使用,无论是作为父级还是解析器。
argparse - Combining parent parser, subparsers and default values 是其中通过参考复制父母的动作产生的并发症(在改变的缺省值)另一种情况。
谢谢,您的回复在所有要点上都是正确的。我将直接添加选项到subparser而不使用'parents'机制。 – toothgrinder 2014-09-15 21:25:44
你能发布完整的解析代码吗?该论据是否应该是“帮手”? – Forge 2014-09-13 02:11:35
这是一个错字 - 它应该是'help ='配置''。 – hpaulj 2014-09-13 18:10:26