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

652

У меня есть скрипт, который предназначен для использования следующим образом: usage: installer.py dir [-h] [-v]

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

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

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

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

Уолдо Брончарт
источник

Ответы:

825

Используйте 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
Винай Саджип
источник
14
Проделайте ?и *означают тот же самые они означают в регулярных выражениях (т.е. ?требуется 0 или 1, и *требуя 0 или больше)? Если так, то +работает ли так же?
Долан Антенуччи
37
@dolan: Да +, тоже работает. См. Docs.python.org/2/library/argparse.html#nargs для деталей.
Vinay Sajip
2
Есть ли способ получить DIR для отображения в необязательных аргументах? или кажется, что позиционные аргументы должны иметь предшествующий «необязательный» квалификатор. Можно ли зарегистрировать (насколько это касается помощи) это как таковое?
scagnetti
6
@ant Из приведенного выше вы можете видеть, что dir является необязательным (это указывается в квадратных скобках в выводе argparse, указывает на это).
Vinay Sajip
1
Tx! Доступ dir от options.dir, а не args.dir, как я пытался!
Птим
69

Как продолжение ответа @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='?' Документы говорят: «?». Один аргумент будет использован из командной строки, если это возможно, и будет создан как один элемент. Если аргумент командной строки отсутствует, будет создано значение по умолчанию.

Матас Вайткявичюс
источник
3
Следует отметить, однако, что nargs='?'не производит список.
Acumenus
@ABB Последняя строка ответа Generally this means a single command-line argument will be consumed and a single item (not a list) will be produced.Надеюсь, это поможет ...
Матас Вайткявичюс
1
Строка в кавычках относится к случаю не определения nargs, а nargs='?'определения его. В документах говорят: «?». Один аргумент будет использован из командной строки, если это возможно, и будет создан как один элемент. Если аргумент командной строки отсутствует, будет создано значение по умолчанию.
Acumenus
@ABB Просто отредактируйте ответ, если вы чувствуете, что чего-то не хватает. Спасибо.
Матас Вайткявичюс
В чем разница между ними nargs=argparse.REMAINDERи nargs='*', как мне кажется, они идентичны по своему действию (протестировано в Python 2.7.10 и Python 3.6.1)?
-5

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()
rakhee
источник
11
OP спрашивал о позиционных параметрах, а не о «--dir». 'required' - неверный аргумент для позиционеров. И «ложь» была опечаткой, она имела в виду «ложь». +1 для новичка, -1 для разгильдяйства.
SoloPilot