, Это побочный эффект изменений, сделанных некоторое время назад, а не хорошо продуманная функция.

я есть следующий код вscript.py:

import argparse

parser = argparse.ArgumentParser()
sp = parser.add_subparsers(dest='command')
sp.default = 'a'

a_parser = sp.add_parser('a')
b_parser = sp.add_parser('b')

a_parser.add_argument('--thing', default='thing')
b_parser.add_argument('--nothing', default='nothing')

args = parser.parse_args()
print(args)

Я могу назвать это тремя разными способами:

$ python3 script.py
Namespace(command='a')
$ python3 script.py a
Namespace(command='a', thing='thing')
$ python3 script.py b
Namespace(command='b', nothing='nothing')

Есть только одна проблема с этим: что яхотеть является то, что если я предоставлю нулевые аргументы в командной строке дляa_parser быть тем, кто заканчивает разбор и делает вещи. Очевидно, это не так,sp.default это просто настройкаcommand='a'не то, что я ожидаю, а именно: «О да, пользователь не предоставил никаких аргументов в командной строке, но я знаю, что это должно быть обработаноa_parser, ВотNamespace(command='a', thing='thing')

Есть ли способ, которым яМожно сделать это с argparse? Я искал несколько разных вариантов, но ни один из них действительно не дает того, что мне нужно. Я полагаю, что я мог бы немного поиграть с созданием 3 различных ArgumentParsers и затем передать аргументы каждому из них, хотя это звучит немного грубо.

Есть лучшие варианты?

 larsks26 окт. 2017 г., 22:54
Вы могли бы исследовать рамки командной строки, какутес или жещелчок которые обеспечивают в целом лучшую поддержку для такого рода дизайна.
 Nickpick27 окт. 2017 г., 01:54
лучше использовать докопт

Ответы на вопрос(1)

Решение Вопроса

и они все еще не в Python2. Тот факт, что они являются необязательными в Py3, является ошибкой, которая была введена несколько лет назад. Произошло изменение в тесте для требуемых аргументов, и подпункты (своего рода позиционные) провалились в трещины. Если все сделано правильно, вы должны были явно установить подпапки как необязательные.

Подпарсеры не ведут себя как другие необязательные аргументы, сnargs='?' или помечены безrequired параметр.

В любом случае вашsp.default определяет значение, которое будет помещено вcommand Dest, но это не вызывает использованиеa_parser, Этоcommand='a' никогда не «оценивается».

Использованиеparse_known_args может позволить вам девальвировать оставшиеся строки сa_parser.

Без каких-либо аргументов мы можем сделать:

In [159]: args, extras = parser.parse_known_args([])
In [160]: args
Out[160]: Namespace(command='a')
In [161]: extras
Out[161]: []

Тогда условно бегиa_parser (если команда «а», но не «вещь»)

In [163]: a_parser.parse_args(extras,namespace=args)
Out[163]: Namespace(command='a', thing='thing')

Но если я попытаюсь включить--thing стоимость:

In [164]: args, extras = parser.parse_known_args('--thing ouch'.split())
usage: ipython3 [-h] {a,b} ...
ipython3: error: argument command: invalid choice: 'ouch' (choose from 'a', 'b')

Он пытается разобрать 'ой' как имя подпарапера. Главный парсер ничего не знает о--thing аргумент.

Как я объяснил в другомargparse Сегодня вопрос, парсер верхнего уровня анализирует входные данные, пока не найдет что-то, что соответствует команде 'subparsers' (или в этом примере выдает ошибку). Затем он передает разбор субпарсеру. Он не возобновляет разбор после.

Добавьте аргументы верхнего уровня argparse после аргументов подпарасера

Как установить подпапку по умолчанию с помощью модуля Argparse с Python 2.7

Мой ответ на этот запрос Py2 может работать для вас. Я сначала бегуparse_known_args с анализатором, у которого нет подпарасеров, и условно запустить второй анализатор, который обрабатывает подпарасеры.

In [165]: firstp = argparse.ArgumentParser()
In [166]: args, extras = firstp.parse_known_args('--thing ouch'.split())
In [167]: args
Out[167]: Namespace()

Еслиextras нет вызова «а» или «б»a_parser (в качестве альтернативы просто посмотрите наsys.argv[1:] непосредственно):

In [168]: extras
Out[168]: ['--thing', 'ouch']
In [169]: a_parser.parse_args(extras)
Out[169]: Namespace(thing='ouch')

Или изменитьextras включить отсутствующую команду subparser:

In [170]: extras = ['a']+extras
In [171]: parser.parse_args(extras)
Out[171]: Namespace(command='a', thing='ouch')

В любом слючае,optional субпарсеры не очень хорошо развиты вargparse, Это побочный эффект изменений, сделанных некоторое время назад, а не хорошо продуманная функция.

Ваш ответ на вопрос