如何在python argparse中使用子解析器定义全局选项? [英] How can I define global options with sub-parsers in python argparse?

查看:49
本文介绍了如何在python argparse中使用子解析器定义全局选项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚如何在使用pythons arparse库的子解析器场景中添加全局选项.

I'm trying to figure out how to add global option in a sub-parser scenario with pythons arparse library.

现在我的代码如下:

def parseArgs(self):
    parent_parser = argparse.ArgumentParser(add_help=False)
    parent_parser.add_argument('--debug', default=False, required=False,
        action='store_true', dest="debug", help='debug flag')

    main_parser = argparse.ArgumentParser()
    main_parser.add_argument('--debug', default=False, required=False,
        action='store_true', dest="debug", help='debug flag')

    service_subparsers = main_parser.add_subparsers(title="category",
        dest="category")
    agent_parser = service_subparsers.add_parser("agent",
        help="agent commands", parents=[parent_parser])
    return main_parser.parse_args()

这适用于命令行./test --help,并且--debug选项列为全局:

This works for the command line ./test --help and the --debug option is listed as global:


usage: test [-h] [--debug] {agent} ...

optional arguments:
  -h, --help  show this help message and exit
  --debug     debug flag

category:
  {agent}
    agent     agent commands

但是,当我使用命令行./test agent --help触发代理子解析器时,--debug选项现在不再列为全局选项,而是作为子解析器的选项列出.另外,它现在必须指定为./test agent --debug,并且./test --debug agent不再起作用:

However when I trigger the agent sub-parser with the command line ./test agent --help the --debug option is now no longer listed as a global option but as an option for the sub-parser. Also it must now specified as ./test agent --debug and ./test --debug agent no longer works:


usage: test agent [-h] [--debug]

optional arguments:
  -h, --help  show this help message and exit
  --debug     debug flag

我想做的就是定义--debug是全局的,以便始终可以为所有子解析器指定它,并在帮助输出中适当地列出它.

What I'd like to be able to do is define --debug is global so that it can always be specified for all sub-parsers and appropriately listed as such in the help output.

推荐答案

main_parser将默认值填充到namespace(对于debugFalse);如果遇到--debug,则会将debug更改为True.看到agent字符串时,它将调用子解析器,并将其余的参数字符串以及它一直在使用的名称空间传递给子解析器.

main_parser fills in the defaults into namespace (False for debug); if it encounters --debug it changes debug to True. When it sees the agent string, it calls the subparser, passing it the remaining argument strings, and the namespace that it has been using.

现在,子解析器执行常规的解析器操作-如果填写其参数的默认值,则将default设置为False.如果在其余字符串中遇到--debug,则将其更改为True.否则,它将保持原样.完成后,它将名称空间传递回主解析器,然后由主解析器将其返回给您的代码.

Now the subparser does the normal parser things - if fills in the defaults for its arguments, setting default to False. If it encounters --debug in the remaining strings, it changes that to True. Otherwise it leaves it as is. Once it is done, it passes the namespace back to the main parser, which then returns it to your code.

所以

myprog.py --debug agent --debug

namespace(debug=False)已从False变为True,再由False变为True.

namespace(debug=False) has flipped from False to True to False and back to True.

这是对主解析器(在这种情况下我不喜欢使用'global')和子解析器共享相同的dest的结果.

This a consequence of sharing the same dest for both the main parser (I don't like the use of 'global' in this context), and the subparser.

有一个错误/问题试图稍微改变行为,将子解析器传递给原始"名称空间,然后以某种方式将其结果与主要名称空间合并.但这产生了一些向后兼容的问题.如果需要的话,我可以查一下.

There was a bug/issue that tried to change the behavior a bit, passing the subparser a 'virgin' namespace, and then somehow merging its result with the main one. But that produced some backward compatibility issues. I could look it up if needed.

就目前而言,尝试在主解析器和次解析器中定义相同的可选内容必然会给您和您的用户造成困惑.

For now, trying to define the same optional in both the main and subparser is bound to create confusion for you and your user.

如果我将父母更改为

parent_parser.add_argument('--Debug', action='store_true', help='debug flag')

(不需要默认值,或者如果dest与选项标志相同,则为dest)

(no need for default, or the dest if it is sames as the option flag)

结果命名空间看起来像

1721:~/mypy$ python stack37933480.py --debug agent --Debug
Namespace(Debug=True, category='agent', debug=True)

或者我可以定义

parent_parser.add_argument('--debug', dest='debug1', action='store_true', help='debug flag')

并获得:

1724:~/mypy$ python stack37933480.py --debug agent --debug
Namespace(category='agent', debug=True, debug1=True)

两个位置都有相同的标志,但名称空间中的条目不同.解析后,我可以做类似的事情:

Same flag in both places, but different entries in the namespace. After parsing I could do something like:

args.debug = args.debug or args.debug1

统一两个标志.无论请求哪个帮助,您的用户都将看到"--debug".

to unify the two flags. Your user will see '--debug' regardless of which help asks for.

很抱歉,如果描述有点冗长,但是我认为重要的是要首先了解这种行为.然后解决方案变得更加明显.

Sorry if the description is a bit long winded, but I think it's important to understand the behavior first. Then solutions become more apparent.

在这种情况下,使用父母不会使问题复杂化.我假设您正在使用它只是为了将此调试添加到所有子解析器中.

In this case the use of a parent doesn't complicate the issue. I assume you are using it just to add this debug to all subparsers.

另一个选择是只为主解析器定义debug.是的,次级解析器帮助中将缺少该注释,但是您始终可以在说明中添加注释.

Another option is to just define debug for the main parser. Yes, it will be missing from the subparsers help, but you can always add a note in the description.

==================

===================

子解析器定义采用prog参数.如果未给出,则基于主prog定义.

The subparser definition takes a prog parameter. If not given it is defined base on the main prog.

如果我将prog添加为:

agent_parser = service_subparsers.add_parser("agent",
    prog='myprog.py [--debug] agent',
    help="agent commands", parents=[parent_parser])

子解析器的用法变为:

1824:~/mypy$ python3 stack37933480.py agent -h
usage: myprog.py [--debug] agent [-h] [--debug]

或者我可以将prog添加到add_subparsers定义

or I can add that prog to the add_subparsers definition

service_subparsers = main_parser.add_subparsers(title="category",
    prog='myprog.py [--debug]',
    dest="category")

检查该方法的代码以查看其如何构造默认用法前缀.它包括main位置,但不包括可选位置.

Check the code for that method to see how it constructs the default usage prefix. It includes main positionals, but not optionals.

http://bugs.python.org/issue9351 -在此补丁中,原始开发人员认为用户希望参数的子解析器定义应覆盖主解析器的值和操作.另一方面,您希望主要定义具有优先权.

http://bugs.python.org/issue9351 - in this patch the original developer thought that users would expect the subparser definition of an argument should override the main parser's values and actions. You were, on the other hand, expecting the main definition to have priority.

http://bugs.python.org/issue24251 -但是在9351中提出的更正导致了问题对于其他用户.这就是为什么我认为最好不要在main和sub中定义相同的dest.很难满足每个人的期望.

http://bugs.python.org/issue24251 - but the correction proposed in 9351 caused problems for other users. That's why I think it is better not to define the same dest in the main and sub. It is hard to satisfy everyone's expectations.

这篇关于如何在python argparse中使用子解析器定义全局选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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