2016-10-14 14 views
1

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

Но поскольку --bar может иметь несколько аргументов, пройденный путь не входил в args.files, как исправить это? Благодаря!

import argparse 
parser = argparse.ArgumentParser() 
parser.add_argument('--foo') 
parser.add_argument('--bar', nargs='*') 
parser.add_argument('files', nargs='?') 

cmd = '--foo a --bar b c d ' 
print parser.parse_args(cmd.split()) 
# Namespace(bar=['b', 'c', 'd'], files=None, foo='a') 


cmd = '--foo a --bar b c d /path/to/file1' 
print parser.parse_args(cmd.split()) 
# Namespace(bar=['b', 'c', 'd', '/path/to/file1'], files=None, foo='a') 
+2

Как 'argparse' должен знать, что'/path/to/file1' идет с 'files', а не с' bar'? – mgilson

ответ

1

Вашего аргумент спецификация неотъемлемо неоднозначна (с --bar может принимать бесконечные аргументы, нет хорошего способа сказать, когда она заканчивается, особенно в связи с files не является обязательным), поэтому она требует пользователя устранения неоднозначности. В частности, можно указать, что argparse «это конец раздела переключателей, все последующие аргументы являются позиционными», помещая -- перед позиционной секцией. Если вы делаете:

cmd = '--foo a --bar b c d -- /path/to/file1' 
print parser.parse_args(cmd.split()) 

Вы должны получить:

Namespace(bar=['b', 'c', 'd'], files='/path/to/file1', foo='a') 

(Проверен на PY3, но должны применяться к py2 а)

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

cmd = '/path/to/file1 --foo a --bar b c d' 

или

cmd = '--foo a /path/to/file1 --bar b c d' 

Наконец, вы можете избежать использования nargs='*' для выключателей, учитывая неоднозначность он вводит. Вместо этого, определить --bar быть приняты несколько раз с одного значения на переключателе, накапливая все виды использования в list:

parser.add_argument('--bar', action='append') 

тогда вы передаете --bar несколько раз, чтобы поставить несколько значений по одному, вместо того, чтобы передать его раз со многими значениями:

cmd = '--foo a --bar b --bar c --bar d /path/to/file1' 

 Смежные вопросы

  • Нет связанных вопросов^_^