Does argparse (python) support mutually exclusive groups of arguments?

前端 未结 4 618
醉话见心
醉话见心 2020-12-09 16:55

If I have the arguments \'-a\', \'-b\', \'-c\', \'-d\', with the add_mutually_exclusive_group() function my program will have to use just one of th

4条回答
  •  旧时难觅i
    2020-12-09 17:20

    EDIT: Never mind. Because argparse makes the horrible choice of having to create an option when invoking group.add_argument. That wouldn't be my design choice. If you're desperate for this feature, you can try doing it with ConflictsOptionParser:

    # exclusivegroups.py
    import conflictsparse
    
    parser = conflictsparse.ConflictsOptionParser()
    a_opt = parser.add_option('-a')
    b_opt = parser.add_option('-b')
    c_opt = parser.add_option('-c')
    d_opt = parser.add_option('-d')
    
    import itertools
    compatible_opts1 = (a_opt, b_opt)
    compatible_opts2 = (c_opt, d_opt)
    exclusives = itertools.product(compatible_opts1, compatible_opts2)
    for exclusive_grp in exclusives:
        parser.register_conflict(exclusive_grp)
    
    
    opts, args = parser.parse_args()
    print "opts: ", opts
    print "args: ", args
    

    Thus when we invoke it, we can see we get the desired effect.

    $ python exclusivegroups.py -a 1 -b 2
    opts:  {'a': '1', 'c': None, 'b': '2', 'd': None}
    args:  []
    $ python exclusivegroups.py -c 3 -d 2
    opts:  {'a': None, 'c': '3', 'b': None, 'd': '2'}
    args:  []
    $ python exclusivegroups.py -a 1 -b 2 -c 3
    Usage: exclusivegroups.py [options]
    
    exclusivegroups.py: error: -b, -c are incompatible options.
    

    The warning message doesn't inform you that both '-a' and '-b' are incompatible with '-c', however a more appropriate error message could be crafted. Older, wrong answer below.

    OLDER EDIT: [This edit is wrong, although wouldn't it be just a perfect world if argparse worked this way?] My previous answer actually was incorrect, you should be able to do this with argparse by specifying one group per mutually exclusive options. We can even use itertools to generalize the process. And make it so we don't have to type out all the combinations explicitly:

    import itertools
    compatible_opts1 = ('-a', '-b')
    compatible_opts2 = ('-c', '-d')
    exclusives = itertools.product(compatible_opts1, compatible_opts2)
    for exclusive_grp in exclusives:
        group = parser.add_mutually_exclusive_group()
        group.add_argument(exclusive_grp[0])
        group.add_argument(exclusive_grp[1])
    

提交回复
热议问题