Python argparse: получить имя подпарсерской программы в строке справки
Я пишу анализатор аргументов для модуля Python с различными подпарасерами. Моя цель - иметь общий аргумент, конструктор Argument которого передается нескольким дочерним элементам:
from argparse import ArgumentParser
parser = ArgumentParser(prog = 'master')
parser1 = ArgumentParser(help = None)
parser1.add_argument('foo', type = int, help = 'Number of times to process %(prog)s') # Line of interest
parser2 = ArgumentParser(help = None)
parser2.add_argument('--bar', type = int, default = 0, help = 'Start at this number')
parser3 = ArgumentParser(help = None)
parser3.add_argument('--baz', type = str, default = 'DEFAULT', help = 'Init file with this text')
subparsers = parser.add_subparsers()
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2])
sp2 = subparsers.add_parser('prog2', parents = [parser1, parser3])
parser.parse_args('prog1 -h'.split())
Желаемый результат будет что-то вроде
usage: master prog1 [-h] [--bar BAR] foo
positional arguments:
foo Number of times to process prog1
optional arguments:
-h, --help show this message and exit
--bar Start at this number
Когда я использую эту точную настройку, я получаю master prog1
вместо prog1
в строке помощи для foo
, Что я должен изменить в строке, отмеченной #Line of interest
получить желаемый результат?
2 ответа
Я могу объяснить, что происходит, но, возможно, не смогу предложить решение.
Короткий ответ: sp1.prog
используется как в его usage
формат и как %(prog)s
значение в строке помощи. И это построено с этим usage
линия в виду.
===============
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2])
создает парсер и добавляет аргументы из parents
, add_parser
это метод class _SubParsersAction
(подпункт Действие класс). И prog
Атрибут для этого парсера создается с помощью:
if kwargs.get('prog') is None:
kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
Вы должны быть в состоянии увидеть этот атрибут с print(sp1.prog)
(Я ожидаю "мастер прог1"). Это значение, которое используется в usage
в любой строке справки с %(prog)s
,
subparsers._prog_prefix
происходит от parser.prog
(см. add_subparsers
код для деталей). Но вы также можете указать prog
параметр:
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='prog1')
Это должно исправить строку в help
линия. Но это также изменит строку usage
,
Вы также можете дать явный указатель usage
:
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='prog1', usage='master prog1 ...')
Без операции на HelpFormatter
Я не думаю, что вы можете изменить prog
в справочных линиях, не меняя их в использовании.
И учитывая путь parents
работает, вы не можете изменить линию помощи для prog1 foo
не меняя также prog2 foo
, parents
копирует объекты Action по ссылке, поэтому два подпарсера разделяют foo
Объект действия.
Вы много должны отказаться от parents
подход, по крайней мере, для этого аргумента, и жестко закодировать имя. Если вам нужно добавить аргумент в несколько подпарсеров, напишите небольшую служебную функцию, чтобы облегчить это. parents
Механизм - это просто (обычно) удобство, то, что экономит время при наборе текста / редактировании.
===================
Этот модифицированный скрипт проиллюстрирует мои очки
parser = ArgumentParser(prog = 'master')
parser1 = ArgumentParser(add_help = False)
fooarg=parser1.add_argument('foo', type = int, help = 'foo prog: %(prog)s') # Line of interest
parser2 = ArgumentParser(add_help = False)
parser2.add_argument('--bar', type = int, default = 0, help = 'Start at this number')
parser3 = ArgumentParser(add_help = False)
parser3.add_argument('--baz', type = str, default = 'DEFAULT', help = 'Init file with this text')
subparsers = parser.add_subparsers(prog='subparsers')
sp1 = subparsers.add_parser('prog1', parents = [parser1, parser2], prog='name1')
sp2 = subparsers.add_parser('prog2', parents = [parser1, parser3])
#parser.print_help()
# fooarg is an Action for both subparsers
# print(fooarg.help)
# fooarg.help = 'FOO HELP'
print('==>sp1 prog:', sp1.prog)
sp1.print_help()
print('==>sp2 prog:', sp2.prog)
sp2.print_help()
sp1.prog = 'custom'
sp1.print_help()
# addition
fooarg.default = 'default'
fooarg.metavar = 'META'
fooarg.help = 'prog: %(prog)s, dest=%(dest)s, nargs=%(nargs)s, type=%(type)s, default=%(default)s'
sp1.print_help()
Этот последний бит добавляет кучу атрибутов Action к справке. Но prog
единственный, который исходит от parser
:
positional arguments:
META prog: custom, dest=foo, nargs=None, type=int, default=default