在argparse中的子命令之前或之后支持全局参数 [英] Support global arguments before or after sub-command in argparse

查看:32
本文介绍了在argparse中的子命令之前或之后支持全局参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

父母 参数设置为解析器将允许在解析器之间共享通用参数(例如

Setting the parents argument with a parser will allow for sharing common arguments between parsers (e.g. parents and sub-commands). But, applying a base parser to both the parent and sub-command appears to overwrite the value from the parent parser with the value from the sub-command parser when using an argument that has specified the value attribute to with a dest keyword, whether or not the invocation has specified the argument in the sub-command.

如何使用 argparse 模块进行合并父级和子命令中的选项(即,如果其中一个解析器包含该选项,则存储值;如果两个解析器均未指定该选项,则使用默认值;如果两个解析器都指定了该选项,则如何处理无关紧要)?

How can I use argparse module to merge the options in the parent and the sub-command (i.e. store the value if either parser contains the option, use the default if neither parser specifies the option, and it doesn't matter how to handle if both parsers specify the option)?

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))

然后,在外壳中:

> 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 中.仅当用户使用该参数时才写入值.

Using SUPPRESS for the subparser default keeps it from overwriting the parent parser value. A SUPPRESS default is not inserted into the namespace at the start of parsing. A value is written only if the user used that argument.

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)

The patch that last changed this behavior (2014)

https://bugs.python.org/issue9351 子命令上的argparse set_defaults应该覆盖顶层set_defaults

https://bugs.python.org/issue9351 argparse set_defaults on subcommands should override top level set_defaults

https://bugs.python.org/issue27859

这篇关于在argparse中的子命令之前或之后支持全局参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆