Argparse необов'язкові позиційні аргументи?


651

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

dir є позиційним аргументом, який визначається так:

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

Я хочу, dirщоб цей варіант був необов’язковим: коли він не вказаний, він просто повинен бути cwd.

На жаль, коли я не вказую dirаргумент, я отримую Error: Too few arguments.

Відповіді:


825

Використовуйте nargs='?'(або nargs='*' якщо вам знадобиться більше одного dir)

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
чи є якийсь спосіб, щоб директор з'явився в необов'язкових аргументах? або здається, що позиційні аргументи повинні мати попередній "необов'язковий" класифікатор. чи можна зареєструвати (що стосується допомоги) його як такого?
scagnetti

6
@ant З вищезазначеного ви бачите, що dir є необов’язковим (що він відображається у квадратних дужках у аргументаційному висновку це вказує).
Vinay Sajip

1
Тх! Доступ до режисера options.dir, ні args.dir, як я намагався!
ptim

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='?'цей список не дає.
Акумен

@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='?'визначення його. У документах кажуть: «?». Якщо можливо, один аргумент буде використаний у командному рядку та виведений у вигляді одного елемента. Якщо аргументу командного рядка немає, буде створено значення за замовчуванням.
Акумен

@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()

11
ОП запитували про позиційні парами, а не "- dir". 'обов'язково' є недійсним аргументом для позицій. А «помилковий» був помилковим, вона мала на увазі «помилкове». +1 для новачків, -1 для неохайності.
SoloPilot
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.