Does argparse support multiple exclusive arguments?

后端 未结 1 1118
眼角桃花
眼角桃花 2021-01-20 22:32

Let\'s say I have two groups of arguments. You can use any number of arguments from each group but you cannot mix arguments between the groups.

Is there a way to cus

相关标签:
1条回答
  • 2021-01-20 22:55

    I've proposed a patch (or rather patches) that would let you test for general logical combinations of arguments. http://bugs.python.org/issue11588.

    The core of my ideas there is to add a hook just inside parse_args that lets the user test for all logical combinations of arguments. At that it point it has access to a list seen arguments. This list is not available to you outside parse_args (hence the need for a hook). But with appropriate defaults, you can write your own tests that use the args Namespace.

    The difficulties with implementing a general argparse version include:

    a) implementing some sort of nesting groups (in your case several any groups nesting within a xor group)

    b) displaying those groups in a meaningful usage line

    For now your best bet is either implement your problem with subparsers (if it fits), or do your own testing after parsing. And write your own usage.

    Here's a sketch of a generalizable test that could be applied to the args namespace after parsing

    def present(a):
        # test whether an argument is 'present' or not
        # simple case, just check whether it is the default None or not
        if a is not None:
            return True
        else:
            return False
    
    # sample namespace from parser
    args = argparse.Namespace(x1='one',x2=None,y1=None,y2=3)
    
    # a nested list defining the argument groups that need to be tested
    groups=[[args.x1,args.x2],[args.y1,args.y2]]
    
    # a test that applies 'any' test to the inner group
    # and returns the number of groups that are 'present'
    [any(present(a) for a in g) for g in groups].count(True)
    

    If the count is 0, no groups are found, if 1 one group has been found, etc. The hook that I mentioned in the bug issue does the same sort of testing, just using a different present test.

    The normal mutually exclusive test would object if count >1. A required group would object to 0, etc. You could also do something like

    if (present(args.x1) or present(args.x2)) and 
       (present(args.y1) or present(args.y2)): 
       parser.error('too many groups')
    

    ie. some combination of any,all,and,or. But count is a nice way of handling the xor condition.

    0 讨论(0)
提交回复
热议问题