Python 2.7 argparse: Как правильно вставить необязательные мутабельные аргументы?
Моя программа должна включать следующие параметры, правильно разобранные argparse:
- чисто необязательный:
[-h, --help]
и [-v, --version]
- взаимоисключающий:
[-f FILE, --file FILE]
и [-u URL, --url URL]
- необязательно, если выбрано
--url
: [-V, --verbose]
- требуется, если выбрано либо
--file
, либо --url
: [-F, --format FORMAT]
Желаемый шаблон использования:
prog.py [-h] [-v] [-f FILE (-F FORMAT) | -u URL [-V] (-F FORMAT) ]
с требованием -F
, применяемым к обоим членам взаимоисключающей группы.
Не уверен, что это скорее positional.
Так что должно быть возможно запустить:
prog.py -u "http://foo.bar" -V -F csv
и крик синтаксического анализа в случае, если я забыл -F
(как он и предполагал).
Что я сделал до сих пор:
parser = ArgumentParser(decription='foo')
group = parser.add_mutually_exclusive_group()
group.add_argument('-f','--file', nargs=1, type=str, help='')
group.add_argument('-u','--url', nargs=1, type=str, help='')
parser.add_argument('-V','--verbose', action='store_true', default=False, help='')
parser.add_argument('-F','--format', nargs=1, type=str, help='')
Поскольку он имеет "ванильный режим" для запуска без аргументов командной строки, все аргументы должны быть необязательными.
Как я могу реализовать точки 3. и 4. в свой код?
EDIT:
Я пробовал -F
и -u
как подпарамеры, как описано здесь, но подкоманды, похоже, рассматриваются как позиционные, и синтаксический анализатор дает мне error: too few arguments
, если я запускаю это без аргументов.
Ответы
Ответ 1
Использование nargs = 2 и metavar кортежа приближают вашу цель
parser = argparse.ArgumentParser(prog='PROG')
group = parser.add_mutually_exclusive_group()
group.add_argument('-f','--file', nargs=2, metavar=('FILE','FORMAT'))
group.add_argument('-u','--url', nargs=2, metavar=('URL','FORMAT'))
parser.add_argument('-V','--verbose', action='store_true',help='optional with url')
который производит:
usage: PROG [-h] [-f FILE FORMAT | -u URL FORMAT] [-V]
optional arguments:
-h, --help show this help message and exit
-f FILE FORMAT, --file FILE FORMAT
-u URL FORMAT, --url URL FORMAT
-V, --verbose optional with url
Для этого требуется формат вместе с именем файла или URL-адресом, он просто не требует -F
. Как отмечали другие, -V
можно игнорировать в случае -F
.
Я попробовал -f и -u как подпарамеры, как описано здесь, но подкоманды, похоже, рассматриваются как позиционные, и синтаксический анализатор дает мне ошибку: слишком мало аргументов, если я запускаю его без аргументов.
В последней версии (ей) подкоманды больше не рассматриваются как обязательные позиционные элементы. Это было, насколько я могу судить, побочным эффектом изменения сообщения об ошибке, чтобы быть более информативным. Вместо _parse_known_args
выполните:
if positionals:
self.error(_('too few arguments'))
он сканирует _actions
, чтобы увидеть, какие из них требуются, и затем перечисляет их по имени в сообщении об ошибке. Это обсуждается в http://bugs.python.org/issue9253. Я знаю, что это изменение находится в разработке (3.4), а также может быть в 3.3.
Ответ 2
Эти точки могут применяться в optparse
с помощью метода callback, когда присутствует определенная опция.
Однако в argparse
они недоступны.
Вы можете добавить subparser для подкатегории url
и file
и проанализировать их отдельно.
из справки:
Обратите внимание, что объект, возвращаемый parse_args(), будет содержать только атрибуты для основной синтаксический анализатор и подпараметр, который был выбран командной строкой (а не любых других подпараметров). Итак, в приведенном выше примере, когда команда, только атрибуты foo и bar присутствуют, а когда команда b указан только атрибуты foo и baz.
Но я бы просто правильно документировал использование и просто игнорировал аргументы, которые не являются
применимо.
например. пусть эти две командные строки ведут себя точно так же:
prog.py -f FILE -V
prog.py -f FILE