2013-09-09 3 views
4

Я знаю, что подобные вопросы задавали раньше, но я не мог найти точного (также я не мог понять концепцию «nargs» или «subparse» и как это было бы обратиться к моему делу)Добавить аргументы в argparse в зависимости от значения начальных аргументов

Я хочу что-то вроде:

parser = argparse.ArgumentParser() 
parser.add_argument('-mode', choices=['download', 'upload'], required=True) 
parser.add_argument('-d', required=True) 
args = parser.parse_args() 
if args.mode == 'download': 
    parser.add_argument('-f', required=True) 

args = parser.parse_args() 

так требуется -f аргумент только тогда, когда -mode является download иначе оно не должно быть разобрано

+0

'argparse' не имеет взаимно включающих аргументов, о чем вы говорите. Вместо этого вы должны сделать не '-d', а' -f', но включить в сообщение об использовании тот факт, что либо оба, либо оба должны быть указаны, а затем убедитесь, что оба '-d' и' -f' указываются, если они есть. – 2rs2ts

+0

согласен с 2rs2ts – Jblasco

+3

Вы можете использовать [подпараметры] (http://docs.python.org/dev/library/argparse.html#argparse.ArgumentParser.add_subparsers), так что 'download' становится подкомандой с собственным набором (обязательных) флагов. – miku

ответ

5

Что об этом?

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('-mode', choices=['download', 'upload'], required=True) 
parser.add_argument('-d', required=True) 
parser.add_argument('-f') 

args = parser.parse_args() 
if args.mode == 'download' and not args.f: 
    parser.error('-f argument is required in "download" mode.') 

DEMO:

$ python test.py -mode=upload -d 10 
$ python test.py -mode=download -d 10 
usage: test.py [-h] -mode {download,upload} -d D [-f F] 
test.py: error: -f argument is required in "download" mode. 
$ python test.py -mode=download -d 10 -f 10 
5

Как правило, вы должны избегать --options требуется. В этом случае я бы предложил следующее:

  1. Заменить --mode с подкомандой.
  2. Заменить -d с позиционным аргументом
  3. Заменить -f с 2-позиционным аргументом в пользу только download команды.

Если вы действительно этого хотите, вы можете оставить -d и -f вместо того, чтобы делать им позиционные аргументы.

Ваши звонки будут выглядеть следующим образом:

./script.py upload d-argument 
./script.py download d-argument f-argument 

или

./script.py upload -d foo 
./script.py download -d foo -f bar 

Код для реализации немного утомительно, но довольно просто.

parser = argparse.ArgumentParser() 
subparsers = parser.add_subparsers() 
upload_parser = subparsers.add_parser('upload') 
download_parser = subparsers.add_parser('download') 
upload_parser.set_defaults(cmd='upload') 
download_parser.set_defaults(cmd='download') 
for p in [ upload_parser, download_parser ]: 
    p.add_argument("d") 
    # p.add_argument("-d", required=True) 
download_parser.add_argument("f") 
# download_parser.add_argument("-f", required=True) 


args = parser.parse_args() 
if args.cmd == 'upload': 
    # handle upload with args.d 
elif args.cmd == 'download': 
    # handle download with args.d and args.f 

Обратите внимание на вызовы set_defaults, используемые для обозначения в конечных проанализированных аргументов, команда была использована.

+0

Отлично, спасибо. Не уверен, что это происходит только для моей моей версии python (3.5), но мне нужно проверить, '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''. – Wtower

+0

Если ваш скрипт вызывается без позиционных аргументов, 'argparse' сам поднимет ошибку. В противном случае первый аргумент будет использоваться для 'cmd'. – chepner

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