【发布时间】:2020-07-15 09:50:05
【问题描述】:
使用解析器will allow for sharing common arguments between parsers(例如parents and sub-commands)设置parents 参数。但是,当使用带有dest 关键字的参数时,将基本解析器应用于父命令和子命令似乎会用来自子命令解析器的值覆盖来自父解析器的值,调用是否在子命令中指定了参数。
如何使用argparse module 合并父命令和子命令中的选项(即,如果任一解析器包含该选项,则存储该值,如果两个解析器均未指定该选项,则使用默认值,没关系如果两个解析器都指定了选项怎么处理)?
sample.py:
from argparse import ArgumentParser
parser = ArgumentParser(add_help=False) # The "base"
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true')
parser.add_argument('-d', '--dir', dest='dir', default=None)
parser_main = ArgumentParser(parents=[parser])
subparsers = parser_main.add_subparsers(dest='command')
subparsers.add_parser('cmd1', parents=[parser])
args = parser_main.parse_args()
print(str(args))
然后,在 shell 中:
> sample.py -v -d abc
Namespace(command=None, dir='abc', verbose=True)
> sample.py -v cmd1 -d abc
Namespace(command='cmd1', dir='abc', verbose=False)
> sample.py -d abc cmd1 -v
Namespace(command='cmd1', dir=None, verbose=True)
> sample.py cmd1 -v -d abc
Namespace(command='cmd1', dir='abc', verbose=True)
【问题讨论】:
-
由于子解析器
namespace是如何用于更新父命名空间的,它的值(包括任何默认值)会破坏相应的父属性。 (我可以向您指出几年前实现此功能的补丁。)无论如何,如果您不希望父dest被覆盖,它们应该是不同的。 -
argparse._SubParsersAction.__call__其中for key, value in vars(subnamespace).items(): setattr(namespace, key, value)进行更新。