Разбор нескольких подкоманд одновременно, используя parse_known_args - PullRequest
0 голосов
/ 14 мая 2018
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='config command help')

# create parser for config command 
parser_config = subparsers.add_parser('config', help='config help')
parser_config.add_argument('--configname', required=True, nargs=1)
parser_config.add_argument('--login', required=True, nargs=1)
parser_config.add_argument('--password', required=True, nargs=1)

parser_config1 = subparsers.add_parser('config1', help='config help')
parser_config1.add_argument('--configname', required=True, nargs=1)
parser_config1.add_argument('--login', required=True, nargs=1)
parser_config1.add_argument('--password', required=True, nargs=1)


rest = 'config --configname name1 --login abc1 --password def1 config1 --configname name2 --login abc2 --password def2'.split()

print(rest)
while rest:
        args,rest =  parser.parse_known_args(rest)
        argslist.append(args)
        print(args, rest)

Дает:

$ python3 create_config.py 
['config', '--configname', 'name1', '--login', 'abc1', '--password', 'def1', 'config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']
Namespace(configname=['name2'], login=['abc2'], password=['def2']) ['config1'] [Namespace(configname=['name2'], login=['abc2'], password=['def2'])]
usage: create_config.py config1 [-h] --configname CONFIGNAME --login LOGIN
                                --password PASSWORD
create_config.py config1: error: the following arguments are required: --configname, --login, --password

Я надеялся увидеть

['config', '--configname', 'name1', '--login', 'abc1', '--password', 'def1', 'config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']
Namespace(configname=['name1'], login=['abc1'], password=['def1']) ['config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']
Namespace(configname=['name2'], login=['abc2'], password=['def2']) []

Как мне это сделать?

1 Ответ

0 голосов
/ 14 мая 2018

Подпарсер config получает:

['--configname', 'name1', '--login', 'abc1', '--password', 'def1', 'config1', '--configname', 'name2', '--login', 'abc2', '--password', 'def2']

Он анализирует

['--configname', 'name1', '--login', 'abc1', '--password', 'def1']

, как и ожидалось.Затем он видит config1, с которым не может справиться (нет positionals).Он помещает это в список extras и продолжает анализировать остальные

['--configname', 'name2', '--login', 'abc2', '--password', 'def2']

, которые перезаписывают предыдущие значения optional's, что вы в конечном итоге видите в args.

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

В любом случае, parse_known_args не просто завершается, когда встречает строку, которую он можетне разбираюсьКак и обычный parse_args, он пытается обработать весь список, только он возвращает остатки в виде списка, а не вызывает ошибку.Допускаются повторные опционные функции, даже если они не приносят никакой пользы (если не определены как append действия).

...