как добавить аргумент добавить взаимоисключающие группы С Python 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]] во взаимоисключающую группу. Не могу понять почему. Кто-нибудь может помочь? Спасибо.

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 который может быть вложенным и может тестироваться для других логических отношений, кроме "xor". "любой" вид принимает любую комбинацию своих аргументов, так же, как вы ожидали, что "argument_group" будет действовать.

в результате использование:

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

основной недостаток дисплей positionals, 'месяц' и 'год'. Они находятся в правильном месте в группе "any", но они также отображаются в обычном трейлинге для позиционных.

он принимает входные данные, такие как:

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

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

как вы можете видеть, расширение понятия групп не является тривиальным. Я думаю, что я на правильном пути, но все еще есть острые углы.