对于 argparse,子解析器本质上是相互排斥的吗?

With argparse are subparsers inherently mutually exclusive?

我有一个具有两个主要功能的脚本,即升级和配置。我正在使用子解析器来指示脚本正在执行的操作,但我想避免将它们一起使用。

这是代码片段:

import argparse

def main():
    parser = argparse.ArgumentParser()
    subparser = parser.add_subparsers(help='sub-command help')
    parser.add_argument('--user', '-u', help='User', default=None, required=True)
    parser.add_argument('--password', '-p', help='Password', default=None, required=True)
    parser.add_argument('--server', '-s', help='server with Admin functionality', default=None, required=True)
    subparser_prov = subparser.add_parser('provision', help='Provision new managers')
    subparser_prov.set_defaults(which='provision')
    subparser_upgr = subparser.add_parser('upgrade', help='Upgrade worker by replacing them')
    subparser_upgr.set_defaults(which='upgrade')
    subparser_upgr.add_argument('--version', help='Deployment version', default=None)
    args = vars(parser.parse_args())

    print args['user']
    print args['password']

    if args['which'] == 'provision':
        print 'Provisioning new environment!'
    elif args['which'] == 'upgrade':
        print 'Upgrading workers! %s' % args['version']

if __name__ == "__main__":
    main()

我知道解析器和子解析器都支持 add_mutually_exclusive_group() 但是这是专门针对参数的。对于子解析器,有什么方法可以避免它们一起使用吗?

据我所知,默认情况下子解析器是互斥的:

Note that the object returned by parse_args() will only contain attributes for the main parser and the subparser that was selected by the command line (and not any other subparsers). So in the example above, when the a command is specified, only the foo and bar attributes are present, and when the b command is specified, only the foo and baz attributes are present.

来自python documentation on subparsers.

是的,它们是互斥的,尽管机制与 MXGroups 不同。

subparser = parser.add_subparsers(help='sub-command help')

是一个 add_argument 命令,它创建一个 positional 参数,带有一个特殊的 action class。除其他外,它还有一个 choices 值。

subparser.add_parser(...)

创建一个 parser,并将其 'name'(和别名)添加到 subparserchoices

一个位置参数只被解析一次,所以只会处理一个子解析器。并且子解析器通常会处理所有剩余的参数。

有很多问题询问如何解决这个问题——他们想要处理多个子解析器。这样做的方法很棘手,涉及递归(或重复)调用解析器,每次使用较小的一组原始参数。