Необязательные позиционные аргументы argparse?

У меня есть сценарий, который можно использовать так: usage: installer.py dir [-h] [-v]

dir - это позиционный аргумент, который определяется следующим образом:

parser.add_argument('dir', default=os.getcwd())

Я хочу, чтобы dir был необязательным: если он не указан, он должен быть просто cwd.

К сожалению, когда я не указываю аргумент dir, я получаю Error: Too few arguments.


person Waldo Bronchart    schedule 18.12.2010    source источник


Ответы (3)


Используйте nargs='?' (или nargs='*', если вам нужно более одного каталога)

parser.add_argument('dir', nargs='?', default=os.getcwd())

расширенный пример:

>>> import os, argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-v', action='store_true')
_StoreTrueAction(option_strings=['-v'], dest='v', nargs=0, const=True, default=False, type=None, choices=None, help=None, metavar=None)
>>> parser.add_argument('dir', nargs='?', default=os.getcwd())
_StoreAction(option_strings=[], dest='dir', nargs='?', const=None, default='/home/vinay', type=None, choices=None, help=None, metavar=None)
>>> parser.parse_args('somedir -v'.split())
Namespace(dir='somedir', v=True)
>>> parser.parse_args('-v'.split())
Namespace(dir='/home/vinay', v=True)
>>> parser.parse_args(''.split())
Namespace(dir='/home/vinay', v=False)
>>> parser.parse_args(['somedir'])
Namespace(dir='somedir', v=False)
>>> parser.parse_args('somedir -h -v'.split())
usage: [-h] [-v] [dir]

positional arguments:
  dir

optional arguments:
  -h, --help  show this help message and exit
  -v
person Vinay Sajip    schedule 18.12.2010
comment
Означают ли ? и * то же самое, что они означают в регулярных выражениях (т.е. ? требует 0 или 1, а * требует 0 или более)? Если да, то + тоже работает? - person Dolan Antenucci; 08.01.2013
comment
@dolan: Да, + тоже работает. См. docs.python.org/2/library/argparse.html#nargs для подробностей. - person Vinay Sajip; 09.01.2013
comment
есть ли способ заставить dir отображаться в необязательных аргументах? или кажется, что позиционные аргументы должны иметь предшествующий «необязательный» квалификатор. можно ли его зарегистрировать (что касается помощи) как таковое? - person scagnetti; 16.09.2014
comment
@ant Из вышесказанного вы можете видеть, что dir является необязательным (на это указывает то, что он появляется в квадратных скобках в выводе argparse). - person Vinay Sajip; 16.09.2014
comment
Тх! Получите доступ к директории options.dir, а не args.dir, как я пытался! - person ptim; 02.02.2018
comment
Вот обновленная документация (Python 3) - внимательное прочтение все объясняет: docs.python.org/3/library/argparse.html#nargs. Для тех, кто не знаком с модулем argparse, начните с учебника: docs.python.org/3 /howto/argparse.html - person Gabriel Staples; 16.05.2019
comment
@dolan и Vinay, '+' не работает, потому что для этого требуется хотя бы один аргумент в командной строке. - person Joonho Park; 04.02.2020

Как расширение ответа @VinaySajip. Есть еще nargs, о которых стоит упомянуть.

  1. parser.add_argument('dir', nargs=1, default=os.getcwd())

N (целое число). N аргументов из командной строки будут собраны вместе в список

  1. parser.add_argument('dir', nargs='*', default=os.getcwd())

'*'. Все имеющиеся аргументы командной строки собраны в список. Обратите внимание, что, как правило, не имеет особого смысла использовать более одного позиционного аргумента с nargs='*', но возможно несколько дополнительных аргументов с nargs='*'.

  1. parser.add_argument('dir', nargs='+', default=os.getcwd())

'+'. Как и '*', все присутствующие аргументы командной строки собраны в список. Кроме того, сообщение об ошибке будет сгенерировано, если не было хотя бы одного аргумента командной строки.

  1. parser.add_argument('dir', nargs=argparse.REMAINDER, default=os.getcwd())

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

Если аргумент ключевого слова nargs не указан, количество используемых аргументов определяется действием. Обычно это означает, что будет использован один аргумент командной строки и будет создан один элемент (не список).

Изменить (скопировано из комментария @Acumenus) nargs='?' документы говорят: '?'. Один аргумент будет использоваться из командной строки, если это возможно, и создаваться как единый элемент. Если аргумент командной строки отсутствует, будет создано значение по умолчанию.

person Matas Vaitkevicius    schedule 06.07.2015
comment
Однако следует отметить, что nargs='?' не создает список. - person Acumenus; 05.10.2016
comment
@ A-B-B Последняя строка ответа Generally this means a single command-line argument will be consumed and a single item (not a list) will be produced. Надеюсь, это поможет ... - person Matas Vaitkevicius; 05.10.2016
comment
Строка в кавычках относится к случаю, когда nargs не определяется, но nargs='?' определяет его. В документах написано: '?'. Один аргумент будет использоваться из командной строки, если это возможно, и создаваться как отдельный элемент. Если аргумент командной строки отсутствует, будет создано значение по умолчанию. - person Acumenus; 05.10.2016
comment
@ A-B-B Просто отредактируйте ответ, если чувствуете, что чего-то не хватает. Спасибо. - person Matas Vaitkevicius; 05.10.2016
comment
В чем разница между nargs=argparse.REMAINDER и nargs='*', как мне кажется, они идентичны по своему действию (проверено на Python 2.7.10 и Python 3.6.1)? - person ; 08.08.2018

parser.add_argument также имеет переключатель требуется. Вы можете использовать required=False. Вот пример фрагмента кода Python 2.7:

parser = argparse.ArgumentParser(description='get dir')
parser.add_argument('--dir', type=str, help='dir', default=os.getcwd(), required=False)
args = parser.parse_args()
person rakhee    schedule 01.12.2016
comment
OP спрашивал о позиционных параметрах, а не о -dir. "required" - недопустимый аргумент для позиционных чисел. И «ложь» была опечаткой, она имела в виду «Ложь». +1 за новичка, -1 за разгильдяйство. - person SoloPilot; 04.12.2016
comment
Мы не можем использовать required в качестве позиционного аргумента. - person Karthik Sunil; 19.08.2020