Как позволить позиционному аргументу и агрегатному аргументу сосуществовать в python argparse? - PullRequest
0 голосов
/ 30 ноября 2018

У меня есть один позиционный аргумент bar и другой аргумент foo, который анализирует список:

import argparse
p = argparse.ArgumentParser()
p.add_argument('-foo', nargs='+')
p.add_argument('bar')

Если bar продолжается foo, все отлично работает

print(p.parse_args('b -foo f1 f2 f3'.split()))

Это приводит к Namespace(bar='b', foo=['f1', 'f2', 'f3']).

Однако, если bar после foo, он жалуется, что bar не предоставлено, то есть

print(p.parse_args('-foo f1 f2 f3 b'.split()))

вызывает

использование: main .py [-h] [-foo FOO [FOO ...]] бар main .py: ошибка: необходимы следующие аргументы: bar

Немного прискорбно, что подсказка об использовании фактически предлагает неправильный порядок.

На самом деле, я добавляю nargs='+' к существующемусинтаксический анализатор для добавления функциональности, и где-то могут быть скрипты с «неправильным» порядком, то есть -foo продолжается bar.И я не хочу их ломать / исправлять.

Один из возможных способов - использовать вместо

p.add_argument('-foo', action='append')

Тогда команду нужно запустить с помощью

print(p.parse_args('-foo f1 -foo f2 -foo f3 b'.split()))

Это решает проблему, но немного многословно.Это лучшее, что можно сделать?

1 Ответ

0 голосов
/ 30 ноября 2018

Не существует простого решения, о котором я знаю.Если хотите, я могу найти ошибку / проблему, которая обсуждает эту проблему.

Во-первых, в отношении использования - код использования разделяет дополнительные и позиционные значения и отображает последние позиционные значения, примерно соответствующие обычным методам POSIX.Конечно, вы можете написать свою собственную строку использования.

Что касается синтаксического анализа, он чередует синтаксический анализ позиционных и дополнительных функций.При обработке позиционеров он распределяет строки (до следующей строки флага) в соответствии с nargs (несколько позиционеров могут обрабатываться одновременно).И при обработке необязательного, он распределяет значения в соответствии с его nargs.

Так что в вашем случае --foo с + возвращает все до следующего флага (или '-'), не резервируячто-нибудь для позиционного, который может последовать.

Резервирование одной строки для bar потребует некоторого вида заблаговременного просмотра.Это не тривиальная вещь, чтобы добавить к существующему коду.

...