Argparse неверный порядок позиционных и необязательных параметров

Почему argparse не анализирует эти аргументы?

--foo 1 2 3 bar

С использованием

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

что дает следующую ошибку:

ошибка: слишком мало аргументов

Если я сначала передам аргумент bar, он сработает:

bar --foo 1 2 3   

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

использование: argparsetest.py [-h] [--foo FOO [FOO ...]] бар

Так как же заставить это работать с последовательным текстом справки?

Вот полная тестовая программа.


person Reimund    schedule 02.05.2011    source источник
comment
Столкнулся с той же проблемой только сейчас. Можно использовать -- для завершения подстановки nargs, поэтому --foo 1 2 3 -- bar должно работать в приведенном выше примере. На мой взгляд, это действительно должно решаться автоматически, оставляя количество аргументов, необходимых для позиционных аргументов. Обсуждения этого открытого вопроса ведутся на bugs.python.org/issue9338 и bugs.python.org/issue9182 (по крайней мере, это должно быть четко задокументировано).   -  person Daniel Andersson    schedule 21.04.2013
comment
-- чтобы остановить список, это так круто. это мой любимый ответ.   -  person Ulf Gjerdingen    schedule 19.10.2020


Ответы (2)


Может быть, попробуйте сделать флаги --input --output и установить для этих параметров значение required=True в add_argument?

http://docs.python.org/dev/library/argparse.html#the-add-argument-method

person Sweet Sheep    schedule 02.05.2011
comment
Спасибо, это работает и дает мне последовательный текст справки. Единственным недостатком является дополнительная часть флага --input, но я могу с этим смириться. Ваше здоровье - person Reimund; 02.05.2011
comment
Чтобы прояснить ситуацию, предлагается использовать parser.add_argument('--bar', required=True). Затем можно передать следующие аргументы: --foo 1 2 3 --bar bar - person Reimund; 02.05.2011

nargs='+' указывает argparse собрать все оставшиеся аргументы вместе, поэтому bar включается. У него нет волшебного способа догадаться, что вы намереваетесь bar быть значимым аргументом сам по себе, а не частью аргументов, переданных в --foo.

Пример в документации относится к простому аргументу --foo, а не к аргументу с nargs='+'. Обязательно поймите разницу.

person Eli Bendersky    schedule 02.05.2011
comment
Было бы легко реализовать его так, чтобы последние n аргументов обрабатывались как n обязательных позиционных аргументов. Это не волшебство, я думаю, это просто дизайнерское решение. - person Reimund; 02.05.2011