Python ArgumentParser嵌套参数

Python ArgumentParser嵌套参数,python,argparse,Python,Argparse,我想创建具有以下签名的参数解析器: /myapp[-a[-b BVAL]|-c] 换句话说,用户只有在提供参数-a的情况下才能提供参数-BVAL 创建相互排斥的-a和-c组非常容易,但我不知道如何创建关系仅当提供了-a时才允许-b这不完全是您想要的,但可能是您可以使用的添加子parsers()() 做一些类似于: import argparse parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(help='

我想创建具有以下签名的参数解析器:

/myapp[-a[-b BVAL]|-c]

换句话说,用户只有在提供参数
-a
的情况下才能提供参数
-BVAL


创建相互排斥的
-a
-c
组非常容易,但我不知道如何创建关系
仅当提供了-a时才允许-b
这不完全是您想要的,但可能是您可以使用的
添加子parsers()
()

做一些类似于:

import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='sub-command help')
a = subparsers.add_parser('a')
c = subparsers.add_parser('c')
a.add_argument('b')

如果不想使用子parser,可以使用parser.error自己处理参数值

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-a', dest='a', default='')  # you can use other defaults surely
parser.add_argument('-b', dest='b', default='')
parser.add_argument('-c', dest='c', default='')

args = parser.parse_args()

if args.b and not args.a:
    parser.error("Option 'b' can't be specified without 'a'")

但仍然考虑使用子分析器以防扩展逻辑

,您可以从AguttPrScript继承,以添加一些自定义功能。这里我提出了一个例外,但是您可以修改它来实现您想要的任何东西。只需更改
on\u dependency\u error()
方法即可满足您的需要

from argparse import ArgumentParser

class FancyParser(ArgumentParser):
    # {'b': 'a'} Where b depends on a
    dependencies = {}

    def on_dependency_error(self, arg, depends_on):
        raise FancyParser.DependencyError(
                    'Argument %s depends on %s' % (arg, depends_on))

    def add_argument(self, *args, **kwargs):
        depends_on = kwargs.get('depends_on')
        if depends_on:
            self.dependencies[kwargs.get('dest') or args[0]] = depends_on
            del kwargs['depends_on']
        return super(FancyParser, self).add_argument(*args, **kwargs)

    def parse_args(self, *args, **kwargs):
        args = super(FancyParser, self).parse_args(*args, **kwargs)
        for arg, depends_on in self.dependencies.iteritems():
            if getattr(args, arg) and not getattr(args, depends_on):
                self.on_dependency_error(arg, depends_on)
        return args

    class DependencyError(Exception):
        def __init__(self, *args, **kwargs):
            return super(FancyParser.DependencyError,
                         self).__init__(*args, **kwargs)
然后你可以这样使用它-

args = ['-a', '-b', 'BVAL', '-c']
parser = FancyParser()
parser.add_argument('-a', dest='a', action='store_true')
parser.add_argument('-b', dest='b', depends_on='a')
parser.add_argument('-c', dest='c', action='store_true')
try:
    parser.parse_args(args)
except FancyParser.DependencyError as e:
    # Whatever here...
    pass
照我的意思做。太棒了

docopt('./myapp [-a [-b BVAL] | -c]')

是的,这听起来很合理。让我们拭目以待,如果有人能提供任何更接近我所寻找的解决方案。如果没有更好的答案,我会选择subparsers,谢谢。subparsers是我以前用于此目的的工具。没问题!刚刚更新了
parse_args()
方法,以更好地测试依赖性。您需要使用更新的代码。谢谢这需要在标准库中!你看到过多少问题,有人发布了他们想要的使用文档,但却无法让argparse为他们创建它?这是倒退和错误的。我们知道如何解释使用文档。为什么我们的代码不能?Docopt有。