parents
参数将允许在解析器之间共享公共参数(例如父命令和子命令)。但是,当使用使用 dest
关键字指定 value 属性的参数时,将基本解析器应用于父命令和子命令似乎会用子命令解析器的值覆盖父解析器的值,调用是否在子命令中指定了参数。如何使用
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)
SUPPRESS
作为子解析器默认值可防止其覆盖父解析器值。 在解析开始时,
SUPPRESS
默认值不会插入到
namespace
中。 仅当用户使用该参数时才会写入值。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--foo', default='foobar')
parser.add_argument('-v', '--verbose', action='store_const', default=False, const=True)
sp = parser.add_subparsers(dest='cmd')
sp1 = sp.add_parser('cmd1')
sp1.add_argument('-f', '--foo', default=argparse.SUPPRESS)
sp1.add_argument('-v', '--verbose', action='store_const', default=argparse.SUPPRESS, const=True)
args = parser.parse_args()
print(args)
样本运行:
1833:~/mypy$ python3 stack62904585.py
Namespace(cmd=None, foo='foobar', verbose=False)
1834:~/mypy$ python3 stack62904585.py --foo FOO -v
Namespace(cmd=None, foo='FOO', verbose=True)
1834:~/mypy$ python3 stack62904585.py cmd1
Namespace(cmd='cmd1', foo='foobar', verbose=False)
1834:~/mypy$ python3 stack62904585.py -v cmd1 -f bar
Namespace(cmd='cmd1', foo='bar', verbose=True)
最后改变此行为的补丁(2014)
https://bugs.python.org/issue9351 子命令上的 argparse set_defaults 应覆盖顶级 set_defaults
还有dest
关键字指定不同的名称来将值存储在不同的属性中:
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()
parser_main.add_argument('-v', '--verbose', dest='g_verbose', action='store_true')
parser_main.add_argument('-d', '--dir', dest='g_dir', default=None)
subparsers = parser_main.add_subparsers(dest='command')
subparsers.add_parser('cmd1', parents=[parser])
args = parser_main.parse_args()
verbose = args.verbose or args.g_verbose if hasattr(args, 'verbose') else args.g_verbose
d = (args.g_dir if args.dir is None else args.dir) if hasattr(args, 'dir') else args.g_dir
parse_known_args()
的通用参数,然后是在第一遍生成的命名空间中传递的所有其他参数。
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true')
parser.add_argument('-d', '--dir', dest='dir', default=None)
parser_main = ArgumentParser()
subparsers = parser_main.add_subparsers(dest='command')
subparsers.add_parser('cmd1')
args,remaining_args = parser.parse_known_args()
parser_main.parse_args(remaining_args, namespace=args)
print(str(args))