2014-07-08 39 views
5

我想实现如下:如何add_argument_group与蟒蛇add_mutually_exclusive_group argparse

$ prog.py -h 
usage: prog.py [-h] [-s | -m] [[-y [year]] | [[-1 | -3] [month] [year]]] 

但是,不管我怎么打了add_argument_group和add_mutually_exclusive_group,

#!/usr/bin/env python 

import argparse 

def main(opt): 
    print(opt) 

if __name__ == '__main__': 

    parser = argparse.ArgumentParser() 
    bar = parser.add_mutually_exclusive_group() 
    bar.add_argument('-s', action='store_true', default=True) 
    bar.add_argument('-m', action='store_true', default=False) 

    #bar = parser.add_argument_group() 
    bar = parser.add_mutually_exclusive_group() 
    bar.add_argument('-y', metavar='year', type=int, 
        dest='iy', nargs='?', default=0) 
    baz = bar.add_argument_group() 
    g_13 = baz.add_mutually_exclusive_group() 
    g_13.add_argument('-1', dest='i1', 
         help='Display single month output.', 
         action='store_true', default=True) 
    g_13.add_argument('-3', dest='i3', 
         help='Display prev/current/next month output.', 
         action='store_true', default=False) 
    #aaa = bar.add_argument_group() 
    baz.add_argument(metavar='month', type=int, 
         choices=range(1, 13), 
         dest='mo', nargs='?', default=1) 
    baz.add_argument(metavar='year', type=int, 
         dest='yr', nargs='?', default=2000) 

    main(parser.parse_args()) 

我只能管理:

$ prog.py -h 
usage: prog.py [-h] [-s | -m] [-y [year]] [-1 | -3] [month] [year] 

也就是说,我不能组[-y [year]][[-1 | -3] [month] [year]]组成一个互斥组。我无法弄清楚为什么。谁能帮忙?谢谢。

+0

可能的重复http://stackoverflow.com/questions/17909294/python-argparse-mutual-exclusive-group – ronakg

回答

4

参数组只是帮助组织帮助显示。它们不能嵌套。相互排斥组测试参数并修改使用情况显示。它们可以嵌套,但最终结果与组建一个大组相同。 http://bugs.python.org/issue11588正试图创建更通用的usage组。

与此同时,您可以编写自定义使用行,并在解析后测试参数,如果相互排斥的组不给予足够的控制。


下面是我开发http://bugs.python.org/issue11588

parser = argparse.ArgumentParser(formatter_class=argparse.UsageGroupHelpFormatter) 

bar = parser.add_usage_group(kind='mxg', dest='s|m') 
bar.add_argument('-s', action='store_true', default=True) 
bar.add_argument('-m', action='store_true', default=False) 

bar = parser.add_usage_group(kind='mxg', dest='year|more') 
bar.add_argument('-y', metavar='year', type=int,...) 

baz = bar.add_usage_group(kind='any', dest='', joiner=' ', parens='[]') 

g_13 = baz.add_usage_group(kind='mxg', dest='1|3') 
g_13.add_argument('-1', dest='i1',...) 
g_13.add_argument('-3', dest='i3',...) 

baz.add_argument(metavar='month', type=int,...) 
baz.add_argument(metavar='year', type=int,...) 

这将替换mutually_exclusive_groupusage_group可以嵌套一个使用解析器代码,并且可以测试除了“异”等逻辑关系。 '任何'种类都接受它的任何参数组合,就像你期望'argument_group'行动一样。

产生的用法是:

usage: prog.py [-h] [-s | -m] [-y [year] | [[-1 | -3] month year]] [month] 
      [year] 

的主要故障是positionals,“月”和“年”的显示。他们在“任何”组中都处于正确的位置,但他们也显示在正常位置的通常尾随位置。

它接受输入等:

'' 
'-y 1943 -s 
'-1 12 1943' 
'12 1943' 
'12' 
'-3' 

'1943' gives an error, because it it is out of range for a month 

正如你可以看到扩大组的概念是不平凡的。我认为我走在了正确的轨道上,但仍然存在着粗糙的边缘。

+0

我以为add_mutually_exclusive_group是add_argument_group的特例。你的add_usage_group似乎是add_argument_group的替代方案吗? –

+0

MEGroup是ArgumentGroup的子类,但2个类之间的重叠很小。它们的用法非常不同,它们也可能是父'_ActionsContainer'的独立子类(它也是'ArgumentParser'的超类)。我的'UsageGroup'是'MEGroup'的一个概念。 – hpaulj

+0

感谢您的澄清。我同意MEGroup和ArgumentGroup应该是_ActionContainer的单独子类。也许下一个版本的Python 3.5中的argparse将包含你的实现。做得好! –