【问题标题】:how to add_argument_group to add_mutually_exclusive_group with python argparse如何使用 python argparse 将_argument_group 添加到 add_mutually_exclusive_group
【发布时间】:2014-08-28 17:15:55
【问题描述】:

我正在尝试实现以下内容:

$ 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]] 分组到一个互斥的组中。我不知道为什么。有人可以帮忙吗?谢谢。

【问题讨论】:

标签: python argparse


【解决方案1】:

参数组只是帮助组织帮助显示。它们不能嵌套。互斥组测试参数并修改使用显示。它们可以嵌套,但最终结果与您创建一个大组相同。 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_group 替换为可以嵌套的usage_group,并且可以测试除“异或”之外的其他逻辑关系。 'any' 类型接受其参数的任意组合,就像您期望 'argument_group' 采取行动一样。

产生的用法是:

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

主要错误是位置的显示,“月”和“年”。它们在“任何”组中的正确位置,但它们也显示在位置的通常尾随位置。

它接受如下输入:

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

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

正如您所见,扩展组的概念并非易事。我认为我在正确的轨道上,但仍然存在粗糙的边缘。

【讨论】:

  • 我以为 add_mutually_exclusive_group 是 add_argument_group 的一个特例。您的 add_usage_group 似乎可以替代 add_argument_group?
  • MEGroup 是 ArgumentGroup 的子类,但两个类之间的重叠很小。它们的用途是如此不同,以至于它们也可能是父 _ActionsContainer 的单独子类(这对于 ArgumentParser 来说也是超级的)。我的UsageGroupMEGroup 理念的概括。
  • 感谢您的澄清。我同意 MEGroup 和 ArgumentGroup 应该是 _ActionContainer 的独立子类。也许 Python 3.5 中 argparse 的下一个版本将包含您的实现。干得好!
猜你喜欢
  • 2018-07-12
  • 1970-01-01
  • 2018-10-05
  • 1970-01-01
  • 2020-05-03
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
相关资源
最近更新 更多